diff --git a/Makefile b/Makefile
index 78cbc31c2..9d2bd3611 100644
--- a/Makefile
+++ b/Makefile
@@ -30,6 +30,8 @@ DOC_FILES := \
config.md \
config-linux.md \
config-solaris.md \
+ features.md \
+ features-linux.md \
glossary.md
default: docs
diff --git a/features-linux.md b/features-linux.md
new file mode 100644
index 000000000..06165eb31
--- /dev/null
+++ b/features-linux.md
@@ -0,0 +1,211 @@
+# Linux Features Document
+
+This document describes the [Linux-specific section](features.md#platform-specific-features) of the [features document](features.md).
+
+## Namespaces
+
+* **`namespaces`** (array of strings, OPTIONAL) The recognized names of the namespaces, including namespaces that might not be supported by the host operating system.
+ The runtime MUST recognize the elements in this array as the [`type` of `linux.namespaces` objects in `config.json`](config-linux.md#namespaces).
+
+### Example
+
+```json
+"namespaces": [
+ "cgroup",
+ "ipc",
+ "mount",
+ "network",
+ "pid",
+ "user",
+ "uts"
+]
+```
+
+## Capabilities
+
+* **`capabilities`** (array of strings, OPTIONAL) The recognized names of the capabilities, including capabilities that might not be supported by the host operating system.
+ The runtime MUST recognize the elements in this array in the [`process.capabilities` object of `config.json`](config.md#linux-process).
+
+### Example
+
+```json
+"capabilities": [
+ "CAP_CHOWN",
+ "CAP_DAC_OVERRIDE",
+ "CAP_DAC_READ_SEARCH",
+ "CAP_FOWNER",
+ "CAP_FSETID",
+ "CAP_KILL",
+ "CAP_SETGID",
+ "CAP_SETUID",
+ "CAP_SETPCAP",
+ "CAP_LINUX_IMMUTABLE",
+ "CAP_NET_BIND_SERVICE",
+ "CAP_NET_BROADCAST",
+ "CAP_NET_ADMIN",
+ "CAP_NET_RAW",
+ "CAP_IPC_LOCK",
+ "CAP_IPC_OWNER",
+ "CAP_SYS_MODULE",
+ "CAP_SYS_RAWIO",
+ "CAP_SYS_CHROOT",
+ "CAP_SYS_PTRACE",
+ "CAP_SYS_PACCT",
+ "CAP_SYS_ADMIN",
+ "CAP_SYS_BOOT",
+ "CAP_SYS_NICE",
+ "CAP_SYS_RESOURCE",
+ "CAP_SYS_TIME",
+ "CAP_SYS_TTY_CONFIG",
+ "CAP_MKNOD",
+ "CAP_LEASE",
+ "CAP_AUDIT_WRITE",
+ "CAP_AUDIT_CONTROL",
+ "CAP_SETFCAP",
+ "CAP_MAC_OVERRIDE",
+ "CAP_MAC_ADMIN",
+ "CAP_SYSLOG",
+ "CAP_WAKE_ALARM",
+ "CAP_BLOCK_SUSPEND",
+ "CAP_AUDIT_READ",
+ "CAP_PERFMON",
+ "CAP_BPF",
+ "CAP_CHECKPOINT_RESTORE"
+]
+```
+
+## Cgroup
+
+**`cgroup`** (object, OPTIONAL) represents the runtime's implementation status of cgroup managers.
+Irrelevant to the cgroup version of the host operating system.
+
+* **`v1`** (bool, OPTIONAL) represents whether the runtime supports cgroup v1.
+* **`v2`** (bool, OPTIONAL) represents whether the runtime supports cgroup v2.
+* **`systemd`** (bool, OPTIONAL) represents whether the runtime supports system-wide systemd cgroup manager.
+* **`systemdUser`** (bool, OPTIONAL) represents whether the runtime supports user-scoped systemd cgroup manager.
+* **`rdma`** (bool, OPTIONAL) represents whether the runtime supports RDMA cgroup controller.
+
+### Example
+
+```json
+"cgroup": {
+ "v1": true,
+ "v2": true,
+ "systemd": true,
+ "systemdUser": true,
+ "rdma": false
+}
+```
+
+## Seccomp
+
+**`seccomp`** (object, OPTIONAL) represents the runtime's implementation status of seccomp.
+Irrelevant to the kernel version of the host operating system.
+
+* **`enabled`** (bool, OPTIONAL) represents whether the runtime supports seccomp.
+* **`actions`** (array of strings, OPTIONAL) The recognized names of the seccomp actions.
+ The runtime MUST recognize the elements in this array in the [`syscalls[].action` property of the `linux.seccomp` object in `config.json`](config-linux.md#seccomp).
+* **`operators`** (array of strings, OPTIONAL) The recognized names of the seccomp operators.
+ The runtime MUST recognize the elements in this array in the [`syscalls[].args[].op` property of the `linux.seccomp` object in `config.json`](config-linux.md#seccomp).
+* **`archs`** (array of strings, OPTIONAL) The recognized names of the seccomp architectures.
+ The runtime MUST recognize the elements in this array in the [`architectures` property of the `linux.seccomp` object in `config.json`](config-linux.md#seccomp).
+* **`knownFlags`** (array of strings, OPTIONAL) The recognized names of the seccomp flags.
+ The runtime MUST recognize the elements in this array in the [`flags` property of the `linux.seccomp` object in `config.json`](config-linux.md#seccomp).
+* **`supportedFlags`** (array of strings, OPTIONAL) The recognized and supported names of the seccomp flags.
+ This list may be a subset of `knownFlags` due to some flags not supported by the current kernel and/or libseccomp.
+ The runtime MUST recognize and support the elements in this array in the [`flags` property of the `linux.seccomp` object in `config.json`](config-linux.md#seccomp).
+
+### Example
+
+```json
+"seccomp": {
+ "enabled": true,
+ "actions": [
+ "SCMP_ACT_ALLOW",
+ "SCMP_ACT_ERRNO",
+ "SCMP_ACT_KILL",
+ "SCMP_ACT_LOG",
+ "SCMP_ACT_NOTIFY",
+ "SCMP_ACT_TRACE",
+ "SCMP_ACT_TRAP"
+ ],
+ "operators": [
+ "SCMP_CMP_EQ",
+ "SCMP_CMP_GE",
+ "SCMP_CMP_GT",
+ "SCMP_CMP_LE",
+ "SCMP_CMP_LT",
+ "SCMP_CMP_MASKED_EQ",
+ "SCMP_CMP_NE"
+ ],
+ "archs": [
+ "SCMP_ARCH_AARCH64",
+ "SCMP_ARCH_ARM",
+ "SCMP_ARCH_MIPS",
+ "SCMP_ARCH_MIPS64",
+ "SCMP_ARCH_MIPS64N32",
+ "SCMP_ARCH_MIPSEL",
+ "SCMP_ARCH_MIPSEL64",
+ "SCMP_ARCH_MIPSEL64N32",
+ "SCMP_ARCH_PPC",
+ "SCMP_ARCH_PPC64",
+ "SCMP_ARCH_PPC64LE",
+ "SCMP_ARCH_S390",
+ "SCMP_ARCH_S390X",
+ "SCMP_ARCH_X32",
+ "SCMP_ARCH_X86",
+ "SCMP_ARCH_X86_64"
+ ],
+ "knownFlags": [
+ "SECCOMP_FILTER_FLAG_LOG"
+ ],
+ "supportedFlags": [
+ "SECCOMP_FILTER_FLAG_LOG"
+ ]
+}
+```
+
+## AppArmor
+
+**`apparmor`** (object, OPTIONAL) represents the runtime's implementation status of AppArmor.
+Irrelevant to the availability of AppArmor on the host operating system.
+
+* **`enabled`** (bool, OPTIONAL) represents whether the runtime supports AppArmor.
+
+### Example
+
+```json
+"apparmor": {
+ "enabled": true
+}
+```
+
+## SELinux
+
+**`selinux`** (object, OPTIONAL) represents the runtime's implementation status of SELinux.
+Irrelevant to the availability of SELinux on the host operating system.
+
+* **`enabled`** (bool, OPTIONAL) represents whether the runtime supports SELinux.
+
+### Example
+
+```json
+"selinux": {
+ "enabled": true
+}
+```
+
+## Intel RDT
+
+**`intelRdt`** (object, OPTIONAL) represents the runtime's implementation status of Intel RDT.
+Irrelevant to the availability of Intel RDT on the host operating system.
+
+* **`enabled`** (bool, OPTIONAL) represents whether the runtime supports Intel RDT.
+
+### Example
+
+```json
+"intelRdt": {
+ "enabled": true
+}
+```
diff --git a/features.md b/features.md
new file mode 100644
index 000000000..18842e309
--- /dev/null
+++ b/features.md
@@ -0,0 +1,341 @@
+# Features Document
+
+A [runtime](glossary.md#runtime) MAY provide a JSON document about its implemented features to [runtime callers](glossary.md#runtime-caller).
+This JSON document is called ["features document"](glossary.md#features-document).
+
+The features document is irrelevant to the actual availability of the features in the host operating system.
+Hence, the content of the feature document SHOULD be determined on the compilation time of the runtime, not on the execution time.
+
+All properties in the features document except `ociVersionMin` and `ociVersionMax` MAY either be absent or have the `null` value.
+The `null` value MUST NOT be confused with an empty value such as `0`, `false`, `""`, `[]`, and `{}`.
+
+## Specification version
+
+* **`ociVersionMin`** (string, REQUIRED) The minimum recognized version of the Open Container Initiative Runtime Specification.
+ The runtime MUST accept this value as the [`ociVersion` property of `config.json`](config.md#specification-version).
+
+* **`ociVersionMax`** (string, REQUIRED) The maximum recognized version of the Open Container Initiative Runtime Specification.
+ The runtime MUST accept this value as the [`ociVersion` property of `config.json`](config.md#specification-version).
+ The value MUST NOT be less than the value of the `ociVersionMin` property.
+ The feature document MUST NOT contain properties that are not defined in this version of the Open Container Initiative Runtime Specification.
+
+### Example
+```json
+{
+ "ociVersionMin": "1.0.0",
+ "ociVersionMax": "1.1.0"
+}
+```
+
+## Hooks
+* **`hooks`** (array of strings, OPTIONAL) The recognized names of the [hooks](config.md#hooks).
+ The runtime MUST support the elements in this array as the [`hooks` property of `config.json`](config.md#hooks).
+
+### Example
+```json
+"hooks": [
+ "prestart",
+ "createRuntime",
+ "createContainer",
+ "startContainer",
+ "poststart",
+ "poststop"
+]
+```
+
+## Mount Options
+
+* **`mountOptions`** (array of strings, OPTIONAL) The recognized names of the mount options, including options that might not be supported by the host operating system.
+ The runtime MUST recognize the elements in this array as the [`options` of `mounts` objects in `config.json`](config.md#mounts).
+ * Linux: this array SHOULD NOT contain filesystem-specific mount options that are passed to the [mount(2)][mount.2] syscall as `const void *data`.
+
+### Example
+
+```json
+"mountOptions": [
+ "acl",
+ "async",
+ "atime",
+ "bind",
+ "defaults",
+ "dev",
+ "diratime",
+ "dirsync",
+ "exec",
+ "iversion",
+ "lazytime",
+ "loud",
+ "mand",
+ "noacl",
+ "noatime",
+ "nodev",
+ "nodiratime",
+ "noexec",
+ "noiversion",
+ "nolazytime",
+ "nomand",
+ "norelatime",
+ "nostrictatime",
+ "nosuid",
+ "nosymfollow",
+ "private",
+ "ratime",
+ "rbind",
+ "rdev",
+ "rdiratime",
+ "relatime",
+ "remount",
+ "rexec",
+ "rnoatime",
+ "rnodev",
+ "rnodiratime",
+ "rnoexec",
+ "rnorelatime",
+ "rnostrictatime",
+ "rnosuid",
+ "rnosymfollow",
+ "ro",
+ "rprivate",
+ "rrelatime",
+ "rro",
+ "rrw",
+ "rshared",
+ "rslave",
+ "rstrictatime",
+ "rsuid",
+ "rsymfollow",
+ "runbindable",
+ "rw",
+ "shared",
+ "silent",
+ "slave",
+ "strictatime",
+ "suid",
+ "symfollow",
+ "sync",
+ "tmpcopyup",
+ "unbindable"
+]
+```
+
+
+## Platform-specific features
+
+* **`linux`** (object, OPTIONAL) [Linux-specific features](features-linux.md).
+ This MAY be set if the runtime supports `linux` platform.
+
+## Annotations
+
+**`annotations`** (object, OPTIONAL) contains arbitrary metadata of the runtime.
+This information MAY be structured or unstructured.
+Annotations MUST be a key-value map that follows the same convention as the Key and Values of the [`annotations` property of `config.json`](config.md#annotations).
+
+### Example
+```json
+"annotations": {
+ "org.opencontainers.runc.checkpoint.enabled": "true",
+ "org.opencontainers.runc.version": "1.1.0"
+}
+```
+
+# Example
+
+Here is a full example for reference.
+
+```json
+{
+ "ociVersionMin": "1.0.0",
+ "ociVersionMax": "1.0.2-dev",
+ "hooks": [
+ "prestart",
+ "createRuntime",
+ "createContainer",
+ "startContainer",
+ "poststart",
+ "poststop"
+ ],
+ "mountOptions": [
+ "acl",
+ "async",
+ "atime",
+ "bind",
+ "defaults",
+ "dev",
+ "diratime",
+ "dirsync",
+ "exec",
+ "iversion",
+ "lazytime",
+ "loud",
+ "mand",
+ "noacl",
+ "noatime",
+ "nodev",
+ "nodiratime",
+ "noexec",
+ "noiversion",
+ "nolazytime",
+ "nomand",
+ "norelatime",
+ "nostrictatime",
+ "nosuid",
+ "nosymfollow",
+ "private",
+ "ratime",
+ "rbind",
+ "rdev",
+ "rdiratime",
+ "relatime",
+ "remount",
+ "rexec",
+ "rnoatime",
+ "rnodev",
+ "rnodiratime",
+ "rnoexec",
+ "rnorelatime",
+ "rnostrictatime",
+ "rnosuid",
+ "rnosymfollow",
+ "ro",
+ "rprivate",
+ "rrelatime",
+ "rro",
+ "rrw",
+ "rshared",
+ "rslave",
+ "rstrictatime",
+ "rsuid",
+ "rsymfollow",
+ "runbindable",
+ "rw",
+ "shared",
+ "silent",
+ "slave",
+ "strictatime",
+ "suid",
+ "symfollow",
+ "sync",
+ "tmpcopyup",
+ "unbindable"
+ ],
+ "linux": {
+ "namespaces": [
+ "cgroup",
+ "ipc",
+ "mount",
+ "network",
+ "pid",
+ "user",
+ "uts"
+ ],
+ "capabilities": [
+ "CAP_CHOWN",
+ "CAP_DAC_OVERRIDE",
+ "CAP_DAC_READ_SEARCH",
+ "CAP_FOWNER",
+ "CAP_FSETID",
+ "CAP_KILL",
+ "CAP_SETGID",
+ "CAP_SETUID",
+ "CAP_SETPCAP",
+ "CAP_LINUX_IMMUTABLE",
+ "CAP_NET_BIND_SERVICE",
+ "CAP_NET_BROADCAST",
+ "CAP_NET_ADMIN",
+ "CAP_NET_RAW",
+ "CAP_IPC_LOCK",
+ "CAP_IPC_OWNER",
+ "CAP_SYS_MODULE",
+ "CAP_SYS_RAWIO",
+ "CAP_SYS_CHROOT",
+ "CAP_SYS_PTRACE",
+ "CAP_SYS_PACCT",
+ "CAP_SYS_ADMIN",
+ "CAP_SYS_BOOT",
+ "CAP_SYS_NICE",
+ "CAP_SYS_RESOURCE",
+ "CAP_SYS_TIME",
+ "CAP_SYS_TTY_CONFIG",
+ "CAP_MKNOD",
+ "CAP_LEASE",
+ "CAP_AUDIT_WRITE",
+ "CAP_AUDIT_CONTROL",
+ "CAP_SETFCAP",
+ "CAP_MAC_OVERRIDE",
+ "CAP_MAC_ADMIN",
+ "CAP_SYSLOG",
+ "CAP_WAKE_ALARM",
+ "CAP_BLOCK_SUSPEND",
+ "CAP_AUDIT_READ",
+ "CAP_PERFMON",
+ "CAP_BPF",
+ "CAP_CHECKPOINT_RESTORE"
+ ],
+ "cgroup": {
+ "v1": true,
+ "v2": true,
+ "systemd": true,
+ "systemdUser": true
+ },
+ "seccomp": {
+ "enabled": true,
+ "actions": [
+ "SCMP_ACT_ALLOW",
+ "SCMP_ACT_ERRNO",
+ "SCMP_ACT_KILL",
+ "SCMP_ACT_LOG",
+ "SCMP_ACT_NOTIFY",
+ "SCMP_ACT_TRACE",
+ "SCMP_ACT_TRAP"
+ ],
+ "operators": [
+ "SCMP_CMP_EQ",
+ "SCMP_CMP_GE",
+ "SCMP_CMP_GT",
+ "SCMP_CMP_LE",
+ "SCMP_CMP_LT",
+ "SCMP_CMP_MASKED_EQ",
+ "SCMP_CMP_NE"
+ ],
+ "archs": [
+ "SCMP_ARCH_AARCH64",
+ "SCMP_ARCH_ARM",
+ "SCMP_ARCH_MIPS",
+ "SCMP_ARCH_MIPS64",
+ "SCMP_ARCH_MIPS64N32",
+ "SCMP_ARCH_MIPSEL",
+ "SCMP_ARCH_MIPSEL64",
+ "SCMP_ARCH_MIPSEL64N32",
+ "SCMP_ARCH_PPC",
+ "SCMP_ARCH_PPC64",
+ "SCMP_ARCH_PPC64LE",
+ "SCMP_ARCH_S390",
+ "SCMP_ARCH_S390X",
+ "SCMP_ARCH_X32",
+ "SCMP_ARCH_X86",
+ "SCMP_ARCH_X86_64"
+ ],
+ "knownFlags": [
+ "SECCOMP_FILTER_FLAG_LOG"
+ ],
+ "supportedFlags": [
+ "SECCOMP_FILTER_FLAG_LOG"
+ ]
+ },
+ "apparmor": {
+ "enabled": true
+ },
+ "selinux": {
+ "enabled": true
+ }
+ },
+ "annotations": {
+ "io.github.seccomp.libseccomp.version": "2.5.4",
+ "org.opencontainers.runc.checkpoint.enabled": "true",
+ "org.opencontainers.runc.commit": "v1.1.0-368-ga1c51c56",
+ "org.opencontainers.runc.version": "1.1.0+dev"
+ }
+}
+```
+
+[mount.2]: https://man7.org/linux/man-pages/man2/mount.2.html
diff --git a/glossary.md b/glossary.md
index 0c81fad8b..7f3b39e96 100644
--- a/glossary.md
+++ b/glossary.md
@@ -17,6 +17,11 @@ For example, namespaces, resource limits, and mounts are all part of the contain
On Linux,the [namespaces][namespaces.7] in which the [configured process](config.md#process) executes.
+## Features Document
+
+A [JSON][] document that represents [the implemented features](#features.md) of the [runtime](#runtime).
+Irrelevant to the actual availability of the features in the host operating system.
+
## JSON
All configuration [JSON][] MUST be encoded in [UTF-8][].
@@ -28,11 +33,20 @@ The order of entries in JSON objects is not significant.
An implementation of this specification.
It reads the [configuration files](#configuration) from a [bundle](#bundle), uses that information to create a [container](#container), launches a process inside the container, and performs other [lifecycle actions](runtime.md).
+## Runtime caller
+An external program to execute a [runtime](#runtime), directly or indirectly.
+
+Examples of direct callers include containerd, CRI-O, and Podman.
+Examples of indirect callers include Docker/Moby and Kubernetes.
+
+Runtime callers often execute a runtime via [runc][]-compatible command line interface, however, its interaction interface is currently out of the scope of the Open Container Initiative Runtime Specification.
+
## Runtime namespace
On Linux, the namespaces from which new [container namespaces](#container-namespace) are [created](config-linux.md#namespaces) and from which some configured resources are accessed.
[JSON]: https://tools.ietf.org/html/rfc8259
[UTF-8]: http://www.unicode.org/versions/Unicode8.0.0/ch03.pdf
+[runc]: https://github.com/opencontainers/runc
[namespaces.7]: http://man7.org/linux/man-pages/man7/namespaces.7.html
diff --git a/runtime.md b/runtime.md
index 9b60d4660..d3aaa9b14 100644
--- a/runtime.md
+++ b/runtime.md
@@ -116,7 +116,7 @@ The remaining `process` properties MAY be applied by this operation.
If the runtime cannot apply a property as specified in the [configuration](config.md), it MUST [generate an error](#errors) and a new container MUST NOT be created.
The runtime MAY validate `config.json` against this spec, either generically or with respect to the local system capabilities, before creating the container ([step 2](#lifecycle)).
-Runtime callers who are interested in pre-create validation can run [bundle-validation tools](implementations.md#testing--tools) before invoking the create operation.
+[Runtime callers](glossary.md#runtime-caller) who are interested in pre-create validation can run [bundle-validation tools](implementations.md#testing--tools) before invoking the create operation.
Any changes made to the [`config.json`](config.md) file after this operation will not have an effect on the container.
diff --git a/schema/features-linux.json b/schema/features-linux.json
new file mode 100644
index 000000000..723ee67b8
--- /dev/null
+++ b/schema/features-linux.json
@@ -0,0 +1,103 @@
+{
+ "linux": {
+ "description": "Linux platform-specific features",
+ "type": "object",
+ "properties": {
+ "namespaces": {
+ "type": "array",
+ "items": {
+ "$ref": "defs-linux.json#/definitions/NamespaceType"
+ }
+ },
+ "capabilities": {
+ "type": "array",
+ "items": {
+ "type": "string",
+ "pattern": "^CAP_[A-Z_]+$"
+ }
+ },
+ "cgroup": {
+ "type": "object",
+ "properties": {
+ "v1": {
+ "type": "boolean"
+ },
+ "v2": {
+ "type": "boolean"
+ },
+ "systemd": {
+ "type": "boolean"
+ },
+ "systemdUser": {
+ "type": "boolean"
+ },
+ "rdma": {
+ "type": "boolean"
+ }
+ }
+ },
+ "seccomp": {
+ "type": "object",
+ "properties": {
+ "enabled": {
+ "type": "boolean"
+ },
+ "actions": {
+ "type": "array",
+ "items": {
+ "$ref": "defs-linux.json#/definitions/SeccompAction"
+ }
+ },
+ "operators": {
+ "type": "array",
+ "items": {
+ "$ref": "defs-linux.json#/definitions/SeccompOperators"
+ }
+ },
+ "archs": {
+ "type": "array",
+ "items": {
+ "$ref": "defs-linux.json#/definitions/SeccompArch"
+ }
+ },
+ "knownFlags": {
+ "type": "array",
+ "items": {
+ "$ref": "defs-linux.json#/definitions/SeccompFlag"
+ }
+ },
+ "supportedFlags": {
+ "type": "array",
+ "items": {
+ "$ref": "defs-linux.json#/definitions/SeccompFlag"
+ }
+ }
+ }
+ },
+ "apparmor": {
+ "type": "object",
+ "properties": {
+ "enabled": {
+ "type": "boolean"
+ }
+ }
+ },
+ "selinux": {
+ "type": "object",
+ "properties": {
+ "enabled": {
+ "type": "boolean"
+ }
+ }
+ },
+ "intelRdt": {
+ "type": "object",
+ "properties": {
+ "enabled": {
+ "type": "boolean"
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/schema/features-schema.json b/schema/features-schema.json
new file mode 100644
index 000000000..30246fa5b
--- /dev/null
+++ b/schema/features-schema.json
@@ -0,0 +1,29 @@
+{
+ "description": "Open Container Initiative Runtime Specification Runtime Features Schema",
+ "$schema": "http://json-schema.org/draft-04/schema#",
+ "type": "object",
+ "properties": {
+ "ociVersionMin": {
+ "$ref": "defs.json#/definitions/ociVersion"
+ },
+ "ociVersionMax": {
+ "$ref": "defs.json#/definitions/ociVersion"
+ },
+ "hooks": {
+ "$ref": "defs.json#/definitions/ArrayOfStrings"
+ },
+ "mountOptions": {
+ "$ref": "defs.json#/definitions/ArrayOfStrings"
+ },
+ "annotations": {
+ "$ref": "defs.json#/definitions/annotations"
+ },
+ "linux": {
+ "$ref": "features-linux.json#/linux"
+ }
+ },
+ "required": [
+ "ociVersionMin",
+ "ociVersionMax"
+ ]
+}
diff --git a/schema/test/features/bad/missing-ociVersionMax.json b/schema/test/features/bad/missing-ociVersionMax.json
new file mode 100644
index 000000000..882ee5960
--- /dev/null
+++ b/schema/test/features/bad/missing-ociVersionMax.json
@@ -0,0 +1,3 @@
+{
+ "ociVersionMin": "1.1.0"
+}
diff --git a/schema/test/features/good/minimal.json b/schema/test/features/good/minimal.json
new file mode 100644
index 000000000..6eed647cb
--- /dev/null
+++ b/schema/test/features/good/minimal.json
@@ -0,0 +1,4 @@
+{
+ "ociVersionMin": "1.0.0",
+ "ociVersionMax": "1.1.0"
+}
diff --git a/schema/test/features/good/runc.json b/schema/test/features/good/runc.json
new file mode 100644
index 000000000..43940a701
--- /dev/null
+++ b/schema/test/features/good/runc.json
@@ -0,0 +1,193 @@
+{
+ "ociVersionMin": "1.0.0",
+ "ociVersionMax": "1.0.2-dev",
+ "hooks": [
+ "prestart",
+ "createRuntime",
+ "createContainer",
+ "startContainer",
+ "poststart",
+ "poststop"
+ ],
+ "mountOptions": [
+ "acl",
+ "async",
+ "atime",
+ "bind",
+ "defaults",
+ "dev",
+ "diratime",
+ "dirsync",
+ "exec",
+ "iversion",
+ "lazytime",
+ "loud",
+ "mand",
+ "noacl",
+ "noatime",
+ "nodev",
+ "nodiratime",
+ "noexec",
+ "noiversion",
+ "nolazytime",
+ "nomand",
+ "norelatime",
+ "nostrictatime",
+ "nosuid",
+ "nosymfollow",
+ "private",
+ "ratime",
+ "rbind",
+ "rdev",
+ "rdiratime",
+ "relatime",
+ "remount",
+ "rexec",
+ "rnoatime",
+ "rnodev",
+ "rnodiratime",
+ "rnoexec",
+ "rnorelatime",
+ "rnostrictatime",
+ "rnosuid",
+ "rnosymfollow",
+ "ro",
+ "rprivate",
+ "rrelatime",
+ "rro",
+ "rrw",
+ "rshared",
+ "rslave",
+ "rstrictatime",
+ "rsuid",
+ "rsymfollow",
+ "runbindable",
+ "rw",
+ "shared",
+ "silent",
+ "slave",
+ "strictatime",
+ "suid",
+ "symfollow",
+ "sync",
+ "tmpcopyup",
+ "unbindable"
+ ],
+ "linux": {
+ "namespaces": [
+ "cgroup",
+ "ipc",
+ "mount",
+ "network",
+ "pid",
+ "user",
+ "uts"
+ ],
+ "capabilities": [
+ "CAP_CHOWN",
+ "CAP_DAC_OVERRIDE",
+ "CAP_DAC_READ_SEARCH",
+ "CAP_FOWNER",
+ "CAP_FSETID",
+ "CAP_KILL",
+ "CAP_SETGID",
+ "CAP_SETUID",
+ "CAP_SETPCAP",
+ "CAP_LINUX_IMMUTABLE",
+ "CAP_NET_BIND_SERVICE",
+ "CAP_NET_BROADCAST",
+ "CAP_NET_ADMIN",
+ "CAP_NET_RAW",
+ "CAP_IPC_LOCK",
+ "CAP_IPC_OWNER",
+ "CAP_SYS_MODULE",
+ "CAP_SYS_RAWIO",
+ "CAP_SYS_CHROOT",
+ "CAP_SYS_PTRACE",
+ "CAP_SYS_PACCT",
+ "CAP_SYS_ADMIN",
+ "CAP_SYS_BOOT",
+ "CAP_SYS_NICE",
+ "CAP_SYS_RESOURCE",
+ "CAP_SYS_TIME",
+ "CAP_SYS_TTY_CONFIG",
+ "CAP_MKNOD",
+ "CAP_LEASE",
+ "CAP_AUDIT_WRITE",
+ "CAP_AUDIT_CONTROL",
+ "CAP_SETFCAP",
+ "CAP_MAC_OVERRIDE",
+ "CAP_MAC_ADMIN",
+ "CAP_SYSLOG",
+ "CAP_WAKE_ALARM",
+ "CAP_BLOCK_SUSPEND",
+ "CAP_AUDIT_READ",
+ "CAP_PERFMON",
+ "CAP_BPF",
+ "CAP_CHECKPOINT_RESTORE"
+ ],
+ "cgroup": {
+ "v1": true,
+ "v2": true,
+ "systemd": true,
+ "systemdUser": true
+ },
+ "seccomp": {
+ "enabled": true,
+ "actions": [
+ "SCMP_ACT_ALLOW",
+ "SCMP_ACT_ERRNO",
+ "SCMP_ACT_KILL",
+ "SCMP_ACT_LOG",
+ "SCMP_ACT_NOTIFY",
+ "SCMP_ACT_TRACE",
+ "SCMP_ACT_TRAP"
+ ],
+ "operators": [
+ "SCMP_CMP_EQ",
+ "SCMP_CMP_GE",
+ "SCMP_CMP_GT",
+ "SCMP_CMP_LE",
+ "SCMP_CMP_LT",
+ "SCMP_CMP_MASKED_EQ",
+ "SCMP_CMP_NE"
+ ],
+ "archs": [
+ "SCMP_ARCH_AARCH64",
+ "SCMP_ARCH_ARM",
+ "SCMP_ARCH_MIPS",
+ "SCMP_ARCH_MIPS64",
+ "SCMP_ARCH_MIPS64N32",
+ "SCMP_ARCH_MIPSEL",
+ "SCMP_ARCH_MIPSEL64",
+ "SCMP_ARCH_MIPSEL64N32",
+ "SCMP_ARCH_PPC",
+ "SCMP_ARCH_PPC64",
+ "SCMP_ARCH_PPC64LE",
+ "SCMP_ARCH_S390",
+ "SCMP_ARCH_S390X",
+ "SCMP_ARCH_X32",
+ "SCMP_ARCH_X86",
+ "SCMP_ARCH_X86_64"
+ ],
+ "knownFlags": [
+ "SECCOMP_FILTER_FLAG_LOG"
+ ],
+ "supportedFlags": [
+ "SECCOMP_FILTER_FLAG_LOG"
+ ]
+ },
+ "apparmor": {
+ "enabled": true
+ },
+ "selinux": {
+ "enabled": true
+ }
+ },
+ "annotations": {
+ "io.github.seccomp.libseccomp.version": "2.5.4",
+ "org.opencontainers.runc.checkpoint.enabled": "true",
+ "org.opencontainers.runc.commit": "v1.1.0-368-ga1c51c56",
+ "org.opencontainers.runc.version": "1.1.0+dev"
+ }
+}
diff --git a/spec.md b/spec.md
index 7237f82df..f27d04439 100644
--- a/spec.md
+++ b/spec.md
@@ -13,11 +13,11 @@ The execution environment is specified to ensure that applications running insid
Platforms defined by this specification are:
-* `linux`: [runtime.md](runtime.md), [config.md](config.md), [config-linux.md](config-linux.md), and [runtime-linux.md](runtime-linux.md).
-* `solaris`: [runtime.md](runtime.md), [config.md](config.md), and [config-solaris.md](config-solaris.md).
-* `windows`: [runtime.md](runtime.md), [config.md](config.md), and [config-windows.md](config-windows.md).
-* `vm`: [runtime.md](runtime.md), [config.md](config.md), and [config-vm.md](config-vm.md).
-* `zos`: [runtime.md](runtime.md), [config.md](config.md), and [config-zos.md](config-zos.md).
+* `linux`: [runtime.md](runtime.md), [config.md](config.md), [features.md](features.md), [config-linux.md](config-linux.md), [runtime-linux.md](runtime-linux.md), and [features-linux.md](features-linux.md).
+* `solaris`: [runtime.md](runtime.md), [config.md](config.md), [features.md](features.md), and [config-solaris.md](config-solaris.md).
+* `windows`: [runtime.md](runtime.md), [config.md](config.md), [features.md](features.md), and [config-windows.md](config-windows.md).
+* `vm`: [runtime.md](runtime.md), [config.md](config.md), [features.md](features.md), and [config-vm.md](config-vm.md).
+* `zos`: [runtime.md](runtime.md), [config.md](config.md), [features.md](features.md), and [config-zos.md](config-zos.md).
# Table of Contents
@@ -33,6 +33,8 @@ Platforms defined by this specification are:
- [Windows-specific Configuration](config-windows.md)
- [Virtual-Machine-specific Configuration](config-vm.md)
- [z/OS-specific Configuration](config-zos.md)
+- [Features Document](features.md)
+ - [Linux-specific Features Document](features-linux.md)
- [Glossary](glossary.md)
# Notational Conventions
diff --git a/specs-go/features/features.go b/specs-go/features/features.go
new file mode 100644
index 000000000..230e88f56
--- /dev/null
+++ b/specs-go/features/features.go
@@ -0,0 +1,125 @@
+// Package features provides the Features struct.
+package features
+
+// Features represents the supported features of the runtime.
+type Features struct {
+ // OCIVersionMin is the minimum OCI Runtime Spec version recognized by the runtime, e.g., "1.0.0".
+ OCIVersionMin string `json:"ociVersionMin,omitempty"`
+
+ // OCIVersionMax is the maximum OCI Runtime Spec version recognized by the runtime, e.g., "1.0.2-dev".
+ OCIVersionMax string `json:"ociVersionMax,omitempty"`
+
+ // Hooks is the list of the recognized hook names, e.g., "createRuntime".
+ // Nil value means "unknown", not "no support for any hook".
+ Hooks []string `json:"hooks,omitempty"`
+
+ // MountOptions is the list of the recognized mount options, e.g., "ro".
+ // Nil value means "unknown", not "no support for any mount option".
+ // This list does not contain filesystem-specific options passed to mount(2) syscall as (const void *).
+ MountOptions []string `json:"mountOptions,omitempty"`
+
+ // Linux is specific to Linux.
+ Linux *Linux `json:"linux,omitempty"`
+
+ // Annotations contains implementation-specific annotation strings,
+ // such as the implementation version, and third-party extensions.
+ Annotations map[string]string `json:"annotations,omitempty"`
+}
+
+// Linux is specific to Linux.
+type Linux struct {
+ // Namespaces is the list of the recognized namespaces, e.g., "mount".
+ // Nil value means "unknown", not "no support for any namespace".
+ Namespaces []string `json:"namespaces,omitempty"`
+
+ // Capabilities is the list of the recognized capabilities , e.g., "CAP_SYS_ADMIN".
+ // Nil value means "unknown", not "no support for any capability".
+ Capabilities []string `json:"capabilities,omitempty"`
+
+ Cgroup *Cgroup `json:"cgroup,omitempty"`
+ Seccomp *Seccomp `json:"seccomp,omitempty"`
+ Apparmor *Apparmor `json:"apparmor,omitempty"`
+ Selinux *Selinux `json:"selinux,omitempty"`
+ IntelRdt *IntelRdt `json:"intelRdt,omitempty"`
+}
+
+// Cgroup represents the "cgroup" field.
+type Cgroup struct {
+ // V1 represents whether Cgroup v1 support is compiled in.
+ // Unrelated to whether the host uses cgroup v1 or not.
+ // Nil value means "unknown", not "false".
+ V1 *bool `json:"v1,omitempty"`
+
+ // V2 represents whether Cgroup v2 support is compiled in.
+ // Unrelated to whether the host uses cgroup v2 or not.
+ // Nil value means "unknown", not "false".
+ V2 *bool `json:"v2,omitempty"`
+
+ // Systemd represents whether systemd-cgroup support is compiled in.
+ // Unrelated to whether the host uses systemd or not.
+ // Nil value means "unknown", not "false".
+ Systemd *bool `json:"systemd,omitempty"`
+
+ // SystemdUser represents whether user-scoped systemd-cgroup support is compiled in.
+ // Unrelated to whether the host uses systemd or not.
+ // Nil value means "unknown", not "false".
+ SystemdUser *bool `json:"systemdUser,omitempty"`
+
+ // Rdma represents whether RDMA cgroup support is compiled in.
+ // Unrelated to whether the host supports RDMA or not.
+ // Nil value means "unknown", not "false".
+ Rdma *bool `json:"rdma,omitempty"`
+}
+
+// Seccomp represents the "seccomp" field.
+type Seccomp struct {
+ // Enabled is true if seccomp support is compiled in.
+ // Nil value means "unknown", not "false".
+ Enabled *bool `json:"enabled,omitempty"`
+
+ // Actions is the list of the recognized actions, e.g., "SCMP_ACT_NOTIFY".
+ // Nil value means "unknown", not "no support for any action".
+ Actions []string `json:"actions,omitempty"`
+
+ // Operators is the list of the recognized operators, e.g., "SCMP_CMP_NE".
+ // Nil value means "unknown", not "no support for any operator".
+ Operators []string `json:"operators,omitempty"`
+
+ // Archs is the list of the recognized archs, e.g., "SCMP_ARCH_X86_64".
+ // Nil value means "unknown", not "no support for any arch".
+ Archs []string `json:"archs,omitempty"`
+
+ // KnownFlags is the list of the recognized filter flags, e.g., "SECCOMP_FILTER_FLAG_LOG".
+ // Nil value means "unknown", not "no flags are recognized".
+ KnownFlags []string `json:"knownFlags,omitempty"`
+
+ // SupportedFlags is the list of the supported filter flags, e.g., "SECCOMP_FILTER_FLAG_LOG".
+ // This list may be a subset of KnownFlags due to some flags
+ // not supported by the current kernel and/or libseccomp.
+ // Nil value means "unknown", not "no flags are supported".
+ SupportedFlags []string `json:"supportedFlags,omitempty"`
+}
+
+// Apparmor represents the "apparmor" field.
+type Apparmor struct {
+ // Enabled is true if AppArmor support is compiled in.
+ // Unrelated to whether the host supports AppArmor or not.
+ // Nil value means "unknown", not "false".
+ Enabled *bool `json:"enabled,omitempty"`
+}
+
+// Selinux represents the "selinux" field.
+type Selinux struct {
+ // Enabled is true if SELinux support is compiled in.
+ // Unrelated to whether the host supports SELinux or not.
+ // Nil value means "unknown", not "false".
+ Enabled *bool `json:"enabled,omitempty"`
+}
+
+// IntelRdt represents the "intelRdt" field.
+type IntelRdt struct {
+ // Enabled is true if Intel RDT support is compiled in.
+ // Unrelated to whether the host supports Intel RDT or not.
+ // Nil value means "unknown", not "false".
+ Enabled *bool `json:"enabled,omitempty"`
+}