SCONE Session Language (v0.3.11)
The SCONE session language is used to create session descriptions that entail all security-relevant details of a SCONE application.
A SCONE application can consist of one or more session descriptions. Each session description defines a set of
- services that are part of the application,
- secrets that are securely stored and passed to the services,
- images that define which regions of a container (image) are encrypted or authenticated,
- volumes which are like docker volumes but encrypted, and
- access policy that defines who can read or modify the session description.
The session language is a subset of YAML, i.e., a session description is valid YAML.
It is similar to and takes its bearing from docker-compose files.
As a session description is typically stored in a file, we use session file
as a somewhat interchangeable synonym for session description.
We use the terms session description
and session policy
(or just policy
) interchangeably.
Changelog
v0.3.11 (SCONE 5.9.0):
v0.3.10 (SCONE 5.8.0):
- Added support for relative paths in secret & volume exports & imports
- Added
volume_alias
in volume exports - Added base32 encoding and URL-safe base64 encoding for binary secrets (secret formats
:base32
,:base32nopad
,:base64url
) - Added SCONE variables in service platform-based attestation, service attestation, and security section; and extended variable replacement in access control policies
- Added configuration fragment secrets
- Added OpenPGP key secrets
- Added session signers in access control policies
- Added Azure Key Vault secret backend
- File permissions of secret injection files can now be controlled in the session
- Added session governance
- Added
san
field for x509 secrets
v0.3.9 (SCONE 5.7.0):
- Added singleton enclaves
- Added service access tokens for 2-factor-authentication
- Added PKCS#12 encoding for X.509 certificates (
:pkcs12-with-private-key
secret format)
v0.3.8 (SCONE 5.6.0):
- Added experimental support for One-Time Passwords for 2-factor-authentication
- Added experimental support for Host Argument Expansion
v0.3.7 (SCONE 5.4.0):
- Added support for AAD tokens to retrieve Microsoft Azure Active Directory tokens
- Allow importing secrets from Azure Key Vault
- Added Microsoft Azure Attestation
- Added new service attestation section, including support for
mrsigner
-based attestation - Allow using secrets as FSPF keys
- Added RSA private key types
- Allow private key migration
v0.3.6 (SCONE 5.3.0):
- Added binary secret format
:base64
- Added secret & volume exports towards namespaces
v0.3.5 (SCONE 5.2.0):
- Added session namespaces
- Added new secret formats
:pem
,:pkcs8:pem
,:der
,:pkcs8:der
,:crt
,:crt:pem
,:crt:der
,:privatekey
,:privatekey:pem
,:privatekey:der
,:privatekey:pkcs8:pem
,:privatekey:pkcs8:der
,:chain
,:bin
,:hex
v0.3.4 (SCONE 5.1.0):
- Added private key types
v0.3.2 (SCONE 4.2.0):
v0.3.1 (SCONE 4.1.0):
- Added the security section, with attestation
mode
,tolerate
andtrusted_scone_qe_pubkeys
fields - Added list representation for service commands
v0.3.0 (SCONE 4.0.0, compared to v0.2):
- The format by which other sessions are referenced for export/import purposes has changed (see Referencing Other Sessions)
- Secrets can now be exported/imported to/from sessions located on another CAS
- Certificates can now be specified as explicit values for
x509
secrets. x509
secrets now require aprivate-key
secret (unless imported or given an explicit value). This allows more fine-grained export rules (exporting only the certificate, but not the private key) and issuing multiple certificates using the same keyx509
secrets have new parameters:private_key
,common_name
,endpoint
,dns
,issuer
,valid_for
- Access Control Policies now use certificate keys instead of entire certificates - certificate hashes have been replaced by certificate key hashes
Session Description Hash
Each session description has a unique hash value, in short just session hash
.
This value is used to reference the session in multiple situations.
For example, when a session shall be updated the hash of the predecessor session has to be provided to ensure continuity, i.e., no lost-updates.
The session hash is deterministically calculated from the session description, such that any modification to the description would yield a different hash. Moreover, the calculation is cryptographically sound in the sense that a malicious operator can not come up with a modified session description that has the same session hash, i.e., it is Preimage-Attack resistant.
The exact procedure of how the session hash is obtained is an implementation detail.
Session Description Structure
There are a number of top-level keys in a session file.
Version
This document describes versions 0.3.10 and older. Always specify the version that provides the set of features you need:
version: "0.3.10"
If a feature does not mention a version, it was introduced with v0.3.0
.
Note
If you are targeting a SCONE version older than 5.8.0, always specify v0.3
(without a minor version).
Warning
Without a version
field, version 0.1 is assumed, make sure to include the field in all session descriptions in order to use version 0.3.x.
Session Name
Every session description has to provide a session name
, or short just name
.
The session name is used to reference a session over the course of its lifetime: while a session hash
identifies a unique, immutable description of a session, the session description referenced by a session name
can be changed by the session's owner.
Thus, the session name
is the primary property with which a session is referenced outside of session management.
As sessions will be routeable in a future version of CAS and session names are the primary way of referencing a session, they have to obey certain restrictions regarding the allowed character set: Only URI "Unreserved Characters" as defined by RFC3986 are permitted, and names can be at most 128 characters long.
In PCRE the match clause matching valid session names would be [A-Za-z0-9_\-.~]{1,128}
.
Example:
name: my-testing-session
Providing a session name is mandatory.
v0.3.5
Namespaces
Sessions can be organized hierarchically, by creating them within the namespace of another session. Organizations and large teams can benefit from namespaces to structure their sessions and restrict the creation and management of nested sessions to a set of authorized users.
In order to create session hello-world
in the namespace of a previously created session my-company
, set the new session's name to:
name: my-company/hello-world
You must have permission to create the session in this namespace.
Namespaces can be nested:
name: my-company/project-1/hello-world
Predecessor Session
If a session description is an update for a previously existing session, i.e. the session's name is already in use, it has to include the previous session's hash to detect and prevent lost updates.
predecessor: e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855
Note
The value has to be 32 hex encoded bytes.
When creating a session, no predecessor session exists and hence no predecessor
key is permitted.
Service Description
Services of a SCONE application are described below the services
top-level key.
A service in a SCONE session is a SCONE program with a specific software state and configuration.
For now, there can be an unlimited number of instances of a service.
In the current version, the service description specifies the service configuration and which software (code) is allowed to access it. A service configuration consists of the command to be executed, any environment variables and the process working directory from which path resolution of relative paths starts. These properties may contain secrets and would be prone to inspection and manipulation by adversaries.
services:
- name: my-test-service
command: test --arg=value
environment:
VAR_1: value
pwd: /
fspf_path: /main.fspf
fspf_key: "66e7935397249112d1148e6ce98a396a8c96b3b0ae70708c16ff284c66f0821e"
fspf_tag: "5a0fe9bdcfed5c0391a707e05f6cfbeb"
name
To be able to identify a service, every service has to have a name
key.
As the name will be part of the routeable session identification in the future, its character set and length is restricted in the same way as the session name is.
name: my-test-service
Providing a service name is mandatory.
command
The command of a service is a sequence of the program's name plus any command-line arguments that have to be provided for it to deliver the expected service.
Note
The first element of the command, the program name, should match the actual program's file name. Although not enforced, in the future automatic scheduling will not function properly if the provided program name does not match.
command: test --arg=value
The command is split at whitespace characters. If spaces should be preserved for an argument, either quote the argument (with single or double quotes):
command: mysql -e "show databases;"
v0.3.5
or use a list instead:
command: ["mysql", "-e", "show databases;"]
Note
Command arguments have to be C-String compatible, i.e., they are not allowed to contain a NULL byte.
environment
The environment variables provide a process with values that are needed to provide the expected service. As we cannot trust pre-existing environment variables, only the environment specified in the session policy will be available to the SCONE program.
environment:
VAR_1: value
Note
- Variable names and values have to be C-String compatible, i.e. they are not allowed to contain the NULL byte. Moreover, variable names are not allowed to contain the equal (=) sign.
- Environment variables that are consumed during enclave creation (e.g.,
SCONE_HEAP
), or used by the SCONE runtime (e.g.,SCONE_CAS_ADDR
) should not be included in the list of environment variables for the service as they will have no effect. Instead, they should be provided directly during program invocation. Note that the value ofSCONE_HEAP
affectsmrenclave
and viamrenclave
, a session description can also limit the set of permittedSCONE_HEAP
values.
pwd
The process working directory (pwd), or current working directory (cwd), is the directory from which relative paths are resolved.
For example, a program writing a private key to private.key
with pwd of /encrypted/
would resolve actually write to /encrypted/private.key
.
Changing the pwd to /plaintext/
before the writing would lead it to write the private key to /plaintext/private.key
instead.
To prevent this kind of manipulation the pwd of a SCONE service has to be specified explicitly in the session description.
pwd: /home/user/scone/encrypted
Note
Please note that: - The specified directory has to exist in the environment the SCONE program will be executed in. If it is not found, the program cannot start. - The provided value has to be C-String compatible, i.e. it is not allowed to contain the NULL byte. - The allowed character may be further restricted by the used file system.
FSPF
The main File System Protection File (FSPF) protects the integrity and confidentiality of the file system used by the service. The main FSPF protects files and directories that are associated with the service, such as optional code stored in shared libraries, images or data source used by the service. Volume FSPFs are better suited to protect file that are transferred between services, for example, as a means of input and output.
Main FSPF are configured with three options:
services:
- name: my_service
fspf_path: /main.fspf
fspf_key: "66e7935397249112d1148e6ce98a396a8c96b3b0ae70708c16ff284c66f0821e"
fspf_tag: "5a0fe9bdcfed5c0391a707e05f6cfbeb"
- The location of the file in the file system is specified in the
fspf_path
option fspf_key
is a 32 byte long hex-encoded encryption key...
v0.3.5
- ... or a reference to a compatible SCONE binary secret (
$$SCONE::<secret-name>$$
) fspf_tag
is a hex-encoded 16 byte value describing the initial filesystem state
Key and tag are obtained from the output of the SCONE CLI upon creation of the FSPF, using the scone fspf create
command.
v0.3.11
Main FSPF Tag Update Policy
By default, service file systems are rollback-protected when an FSPF is enabled: Attempting to restore an old filesystem state and letting a service read files from or write files to this old state will be detected and prevented. In specific cases, however, this may not be the desired behavior. The fspf_update_policy
key can be used to change it:
services:
- name: my_service
fspf_path: /main.fspf
fspf_key: "66e7935397249112d1148e6ce98a396a8c96b3b0ae70708c16ff284c66f0821e"
fspf_update_policy: no_rollback_protection
The following values are possible as a fspf_update_policy
:
rollback_protected_reinitializable
: This is the default setting iffspf_update_policy
is omitted. Services are allowed to alter the filesystem's state, rollbacks will be detected and lead to an error upon access. This ensures a coherent, linear history of filesystem changes. There is one exception to this rule: Filesystems are allowed to roll back to the initial state, given by thefspf_tag
in the session. This is called "reinitializable". It allows multiple services to be started in parallel, each having their own, independent filesystem state.no_rollback_protection
: Services are allowed to alter the filesystem's state and rollback prevention checks are disabled. This option is dangerous, as it also allows third parties to perform rollbacks unnoticed. It should not be necessary for most use cases.fspf_tag
can be omitted with this setting.
Image
A service can optionally use an image, which has to be specified as part of the session (see Section Images).
services:
- name: my_service
image_name: my_image
Images must be specified if their volumes or secret injection files should be used by a service.
Attestation
Attestation is the process of verifying a remote SCONE program's integrity, ensuring it has not been (maliciously) manipulated. SCONE programs have to engage into attestation with CAS to be allowed to access their service's configuration and secrets. That is, only SCONE programs that can show (using attestation) that they satisfy a certain attestation policy are provided with arguments, environment variables, and secrets.
The service-level attestation configuration depends on the session's global attestation security settings. Particularly, if attestation has been disabled for the whole session, then service-level attestation configurations have no effect.
There are a couple of strategies how one can enforce the security goals of an application.
Typically, only one is chosen, but they can also be combined to achieve multi-factor authentication (MFA).
Also note platform restrictions for an additional factor.
The authentication factors are configured in a service's description in the attestation
section.
The attestation
section may hold multiple attestation variants where at least one variant has to be fulfilled by an enclave to gain access.
Note
If attestation is not deactivated globally in the session, each service must specify at least one valid attestation variant. Otherwise, validation of the session will fail. That is because a service without attestation configuration cannot start.
v0.3.7
Attestation Configuration Example
services:
- name: loadbalancer
attestation:
- mrenclave:
- 2c4de8cbe6725f7e11f2f5240bc7e0b7fe0651f2997a48c87ca38918574ef076
- bac31957ee05e5f3f95ea10632008315bf314a536a453dbb787be02c5b920b88
signer:
mrsigner: ce24e0918a348837738a18c4ce7a3afe3aed8acb58ee6ddb6031a570a1e1401c
isvprodid: 6
- signer:
mrsigner: 1190831f4e21529d6702681f2906d5a27cc7cf1900bc323cd1cdedb2dc27edbd
isvprodid: 213
isvsvn_min: 13
The above example allows successful service attestation in any of the following cases:
- The application has either mrenclave
2c4de8cbe6725f7e11f2f5240bc7e0b7fe0651f2997a48c87ca38918574ef076
or mrenclavebac31957ee05e5f3f95ea10632008315bf314a536a453dbb787be02c5b920b88
, and was additionally signed by mrsignerce24e0918a348837738a18c4ce7a3afe3aed8acb58ee6ddb6031a570a1e1401c
with product ID 6 and any security version number. - The application was signed by mrsigner
1190831f4e21529d6702681f2906d5a27cc7cf1900bc323cd1cdedb2dc27edbd
with product ID 213, and has a security version number greater than or equal to 13. Its mrenclave is not being checked.
v0.3.10
SCONE variables of the form $$SCONE::secret_name$$
can be used within the attestation configuration.
This facilitates delegating attestation policies to other sessions (via secret import).
The following sections describe each particular attestation factor, how to obtain application-specific enclave measurement (mrenclave
) and signer identity (mrsigner
) values, as well as how to combine them.
v0.3.7
Code Identity-based Attestation
In Code Identity-based Attestation the Code (and data) that is initially loaded into the enclave is used to authorize access. The reasoning behind this is that this initial enclave state determines the enclave's entire behavior throughout its lifetime. Therefore, knowing the initial state allows the verifier to assess whether the program will handle data confidentially and calculate the expected results. Instead of verifying the code loaded into the enclave directly, which is often impractical due to the code's complexity or availability, a hash representation of the initialized code is compared to a hash or list of hashes of well-behaving code.
SCONE offers two Code Identity-based Attestation mechanisms:
- Measurement-based SGX Attestation uses SGX' enclave measurement value to attest an enclave, while
v0.3.9
- Singleton-based Attestation, is an enhanced mechanism that is based on SGX' enclave measurement values but offers better security.
SCONE Singleton-based Attestation improves over Measurement-based Attestation by ensuring that the enclave is fresh, i.e., it has not been tampered with by an adversary.
If an adversary is able to exploit an enclave and gain control over its execution, they can make the enclave pretend to be a new enclave and query CAS for secrets.
With Measurement-based attestation, CAS is not able to detect such attacks since it only verifies the initial enclave state (before the enclave was exploited).
Singleton-based Attestation enables CAS to establish that an enclave has not been used before and, thus, can not been exploited already.
Note that Singleton-based Attestation is necessary to secure execution of program that dynamically load code (SCONE_ALLOW_DLOPEN
is set).
You'll find more details about Singleton-based Attestation at Singleton Enclaves.
From the usage perspective, Measurement-based SGX Attestation and Singleton-based Attestation are almost identical.
The only difference is that Singleton-based Attestation must be activated by activating the singleton_enclaves
security setting:
security:
singleton_enclaves: true
singleton_enclaves
are deactivated by default due to backwards-compatibility reasons.
Starting with the next session language version singleton_enclaves
will be active by default.
Code Identity-based SGX attestation gives access to service secrets based on the enclave measurement value, abbreviated as mrenclave
.
An enclave measurement value uniquely identifies the enclave's initial state.
The measurement value of a SCONE program can be determined by running it either with SCONE_VERSION
or SCONE_HASH
environment variables set.
For example, if you have an executable go-webserver
you can determine its measurement value by executing:
$ SCONE_HASH=1 ./go-webserver
d08b7351eeb8d5c0653d32794218f183ac9c6fa3923b67052752f78a3559de61
Any modifications to the executable, malicious or not, will void access capabilities using measurement-based attestation.
A service can define a single enclave measurement value, or a list of values that are allowed to get access to the configuration as follows:
services:
- name: my_service
attestation:
mrenclave: d08b7351eeb8d5c0653d32794218f183ac9c6fa3923b67052752f78a3559de61
security:
singleton_enclaves: true
An example in which multiple enclaves have access is shown here:
services:
- name: my_service
attestation:
mrenclave:
- 228be796e784d152987014aae213a536c881533d07c81a224775234cd1c4c290
- e96a21c7f86eae2b311f84c6509dd849ff2ac1da0b8d6c64e0dacba912b6c139
security:
singleton_enclaves: true
For example, you can define mrenclave
s for different permitted HEAP_SIZE
s. Also, to permit a smooth transition to new service versions, you can first add the mrenclaves of the new version, upgrade the services, and then remove the mrenclave
s of the old service version.
Note
The enclave measurement value (mrenclave
) has to be a sequence of 32 hex-encoded bytes.
Warning
Note that some programs' behavior significantly depends on configuration and/or input data. A good example for such programs are interpreted languages (Python, Java, JavaScript, C#, ...). The program code loaded into the enclave for interpreted languages is typically only the code of the interpreter while the user applications code is read from the file system. For such programs additional protection mechanism must be in place to run securely.
Warning
Depending on the concrete enclave program code, not enforcing a particular signer identity can lead to security risks. For example, SGX-derived signer sealing keys depend on the signer identity. If an adversary is able to exchange the enclave's original signature structure with their own, an enclave utilizing such keys would use keys essentially controlled by the adversary.
v0.3.7
Signer-based SGX Attestation
A signer can associate additional data with an enclave, which can be used to authorize access to configuration and secrets in CAS.
This data consists of the signer identity (mrsigner
), a product ID (isvprodid
) and, optionally, a security version number (isvsvn
).
By verifying a trusted enclave signer instead of the enclave's code, software updates can be simplified, as the signer just has to sign the updated enclave, and the session doesn't need to be changed. However, it also puts all trust about the code integrity into the entity controlling the signer identity / private key.
The data associated with a compiled SCONE program can be determined with the scone-signer
tool:
# scone-signer info ./test
SIGSTRUCT:
Header: 06000000e10000000000010000000000
Vendor: 00000000
Date: 00000000
Header #2: 01010000600000006000000001000000
Software defined: 00000000
Modulus: [ .. ]
Exponent: 03000000
Signature: [ .. ]
Misc Select: 00000000
Misc Mask: 00000000
Attributes: 06000000000000000300000000000000
Debug: yes
64-bit Mode: yes
Access to Provisioning Key: no
Access to EINITTOKEN Key: no
XFRM: 0300000000000000
Attributes Mask: 0600000000000000fbffffffffffffff
Debug: yes
64-bit Mode: yes
Access to Provisioning Key: no
Access to EINITTOKEN Key: no
XFRM: fbffffffffffffff
MRENCLAVE: 54b6de36d5d041453e7e00ae13ef7e520754e2785afecd4bbb5a1194ca65e671
ISV Product ID: 12
ISV SVN: 5
Q1: [ .. ]
Q2: [ .. ]
[ .. ]
MRSIGNER: 11c4e150b76c2b145f7fadb6c30455e1046b9e6fbb75b49c6e13341ad8acc5bd
Enclave Parameters:
Number of TCS: 8
Enclave size: 68719476736
Heap size: 67108864
Minimal heap size (EDMM): 20971520
Default stack size: 2097152
Flags:
DLOPEN: not allowed
MPROTECT: disabled
[ .. ]
Some fields have been omitted for brevity.
These values can be set using the tool's sign
command or by specifying SCONE_KEY
, SCONE_ISVPRODID
and/or SCONE_ISVSVN
during compilation with one of the SCONE compilers.
Use the signer
subsection to authorize access based on the signer associated data of an enclave:
services:
- name: my_service
attestation:
signer:
mrsigner: 11c4e150b76c2b145f7fadb6c30455e1046b9e6fbb75b49c6e13341ad8acc5bd
isvprodid: 12
The signer
section must always list a single signer identity (mrsigner
) and a product ID (isvprodid
).
The security version number is optional; if omitted, it is not being checked.
Otherwise, it can be a specific version (isvsvn
), or a range of versions (isvsvn_min
and/or isvsvn_max
).
services:
- name: webserver
attestation:
signer:
mrsigner: 11c4e150b76c2b145f7fadb6c30455e1046b9e6fbb75b49c6e13341ad8acc5bd
isvprodid: 1
isvsvn: 4
- name: database
attestation:
signer:
mrsigner: 11c4e150b76c2b145f7fadb6c30455e1046b9e6fbb75b49c6e13341ad8acc5bd
isvprodid: 2
isvsvn_min: 2
isvsvn_max: 5
In the above example, the webserver program/enclave has product id 1 and only enclaves with an associated security version number of 4 are permitted to access the configuration. The database program/enclave must have product id 2 and the security version number must be 2, 3, 4, or 5.
Note
isvsvn_min
and isvsvn_max
are inclusive.
If there is no upper or lower bound for the security version number, the respective option (isvsn_min
or isvsvn_max
) can be omitted.
Specific versions (isvsvn
) and version ranges (isvsvn_min
and/or isvsvn_max
) cannot be used at the same time.
v0.3.7
Combining Attestation Factors
Code-identity- and signer-based attestation can be combined to yield an attestation schema with stronger guarantees.
services:
- name: my_service
attestation:
mrenclave:
- 2c4de8cbe6725f7e11f2f5240bc7e0b7fe0651f2997a48c87ca38918574ef076
- bac31957ee05e5f3f95ea10632008315bf314a536a453dbb787be02c5b920b88
signer:
mrsigner: 1190831f4e21529d6702681f2906d5a27cc7cf1900bc323cd1cdedb2dc27edbd
isvprodid: 8
In the above example, the enclave has to fulfill both mrenclave and signer requirements in order to pass attestation.
Such a combination has the advantage that the signer doesn't need to be trusted regarding the code's integrity anymore. At the same time, the signer must have also expressed its trust into the program (second factor).
v0.3.7
Independent Attestation Factors
Multiple independent attestation variants can be configured as well:
services:
- name: my_service
attestation:
- mrenclave:
- 2c4de8cbe6725f7e11f2f5240bc7e0b7fe0651f2997a48c87ca38918574ef076
- bac31957ee05e5f3f95ea10632008315bf314a536a453dbb787be02c5b920b88
- signer:
mrsinger: 1190831f4e21529d6702681f2906d5a27cc7cf1900bc323cd1cdedb2dc27edbd
isvprodid: 8
Caution
Please note the difference to the previous example: Here, attestation
is a list (there are dashes in front of mrenclave
and signer
).
Here, two independent attestation variants are configured. One code-identity-based and one signer-based attestation variant. Any enclave fulfilling either variant's requirements is granted access. In this example, that is an encave with one of the two listed enclave measurement values and any signer identity is allowed access, as well as, any enclave signed by the listed signer identity with ISV product ID 8 and any enclave measurement value.
Having more than one attestation configuration enables the definition of more complicated attestation requirements. It becomes necessary, for example, when the signer identity is supposed to be changed and facilitates software updates.
v0.3.0
Deprecated Attestation Configuration
Measurement-based Attestation can also be configured via the legacy mrenclaves
sections.
This configuration variant is deprecated through and will be removed in the next version of the session language.
services:
- name: my_service
mrenclaves:
- d08b7351eeb8d5c0653d32794218f183ac9c6fa3923b67052752f78a3559de61
- b138e442406ee2bd571be7fd8ddd428f21421fb23ebddd6d739d890c81758c8c
The above configuration is equivalent to the following one using the current configuration format.
services:
- name: my_service
attestation:
mrenclave:
- d08b7351eeb8d5c0653d32794218f183ac9c6fa3923b67052752f78a3559de61
- b138e442406ee2bd571be7fd8ddd428f21421fb23ebddd6d739d890c81758c8c
Platform-based Attestation
Platform-based attestation gives access to services that are deployed on a specific platform. This is not sufficiently secure on its own to prevent program manipulation! Thus, platform-based attestation should always be combined with another attestation factor.
The platform
identity is the public key of the SCONE Quoting Enclave (SCONE QE), which is part of the SCONE Local Attestation Service (LAS).
The SCONE QE will have a unique public key on each platform. Platforms that are allowed to get access to the configuration can be specified as follows:
platforms: [2c45c8294d491808aa9b2a6bca01b8e185ffc69266c833546e5dca1c676a6151]
Platform-based attestation requires the SCONE attestation scheme, which is used by default.
Note
The platform identity has to be a sequence of 32 hex-encoded bytes (i.e., 64 characters).
You can determine the public platform key using the SCONE CLI:
$ scone las scone-epid-trust-anchor --las las.server.address
Unverified Information! An adversary could have manipulated this information!
Provide IAS credentials to allow attestation and prevent manipulations
Public Key: 2c45c8294d491808aa9b2a6bca01b8e185ffc69266c833546e5dca1c676a6151
Enclave Measurement: 1bf719b124c4be51edb607ea8f2282b5209c4dfe80b3d7bef2cf492161eaac75
In this example, the platform key is 2c45c8294d491808aa9b2a6bca01b8e185ffc69266c833546e5dca1c676a6151
.
You also find the key in the output of the LAS container:
[10000:INFO@25.03.2021/10:53:17] STARTER: SCONE QE has public key 2C45C8294D491808AA9B2A6BCA01B8E185FFC69266C833546E5DCA1C676A6151
v0.3.10
A platform entry can also be a reference to a SCONE secret:
services:
- name: my_service
platforms:
- 2c45c8294d491808aa9b2a6bca01b8e185ffc69266c833546e5dca1c676a6151
- $$SCONE::platform_2$$
secrets:
- name: platform_2
import:
session: platform_policy
secret: authorized_platform
Secrets
Secrets are defined in the secrets
section of the session.
Each secret is uniquely identified with a name.
The values of secrets are either generated by CAS or are explicitly given in the session.
The former has the advantage that the secret value is never known by any human.
Secret values can be injected into program arguments, environment variables and files (see Secret Injection).
v0.3.10
Character Encoding
Each secret kind provides individual formatting modifiers explained in the respective kind section (see Secret Kinds). For example, using format modifiers, one can obtain a X509 certificate in PEM or DER format. However, the resulting values may not be compatible with your application's expected data format. You may want to use the PEM-encoded x509 certificate in an application's JSON-encoded configuration file. JSON has specific encoding requirements, in particular, it requires newline characters to be escaped. This conflicts with the newlines used in the PEM format. That is, without further processing the certificate can not be used in the JSON config file. This is where character encoding comes into play.
Character encoding takes a previously formatted secret value and applies an encoding, i.e., it modifies the value according to some "rules" such that it is consumable by the application.
Character encodings are appended to the secret value formatting rules using a pipe: $$SCONE:my_secret|escape(json)$$
would apply the escape(json)
encoding to the default format representation of the secret my_secret
.
The following encodings are supported:
- JSON string escaping:
escape(json)
escapes a string secret according to https://www.rfc-editor.org/rfc/rfc7159#section-7 The resulting value can be used in JSON-encoded data. Note that, this escaping does NOT add double-quotes to beginning and end of the secret. These values are compatible with YAML's double-quoted strings (see http://yaml.org/spec/1.2-old/spec.html#id2787109) as well.
Secret Kinds
In most cases, the kind of a secret has to be specified as well. This is necessary for CAS to know how to generate its value or how to interpret the value provided in the session, in the case of explicit secrets.
We support these four kinds of secrets: ASCII, binary, private keys and X.509 certificates (end-entity or CA certificates).
ascii
An ASCII secret is a string comprised of ASCII characters. It is guaranteed not to contain NULL bytes. Generated values can contain any printable ASCII character, including special characters, like /
, \\
, ~
, ```, etc.
Parameters:
size
- the length of generated values, in characters. Optional. Default value:20
Example:
secrets:
- name: my_generated_ascii_secret
kind: ascii
size: 12
- name: my_explicit_ascii_secret
kind: ascii
value: "secret-value"
Secret Placeholders:
Assuming a secret named my_password
, use $$SCONE::my_password$$
in program arguments, environment variables or secret injection files (see Secret Injection). ASCII secrets do not support any format suffix.
binary
binary
secrets behave similar to ascii
secrets except
- they can contain NULL bytes,
- generated values are not restricted to printable ASCII characters, and
- explicit secret values have to be specified encoded as a hexadecimal string.
Parameters:
size
- the length of generated values, in bytes. Optional. Default value:20
Example:
secrets:
- name: my_generated_binary_secret
kind: binary
size: 32
- name: my_explicit_binary_secret
kind: binary
value: DEADBEEF
Secret Placeholders:
Assume a secret named my_secret
:
v0.3.5
$$SCONE::my_secret$$
or$$SCONE::my_secret:bin$$
- binary form. Not suitable for program arguments or environment variables
v0.3.5
$$SCONE::my_secret:hex$$
- hexadecimal string representation (twice as long as binary form). Can also be used in program arguments or environment variables
v0.3.6
-
$$SCONE::my_secret:base64$$
- base64-encoded form
v0.3.10
$$SCONE::my_secret:base64url$$
- URL-safe base64-encoded form
v0.3.10
$$SCONE::my_secret:base32$$
- base32-encoded form
v0.3.10
$$SCONE::my_secret:base32nopad$$
- base32-encoded form without padding
Note
For CAS versions prior to 5.2.0, please use suffix .hex
instead of :hex
. .hex
is still supported in later versions, but has been deprecated.
private-key
Private keys are required when generating X.509 certificates (refer to the next section). Possession of a certificate's private key is necessary in order to sign other certificates or use them as e.g. TLS server or client certificates. Explicit values must be specified as PEM-encoded PKCS#8 private keys.
Warning
By default, private keys will be re-generated when updating a session, even if the secret description did not change.
Set migrate: true
if a private key should be kept (must be present in both old and new session for migration to happen).
See also Secret Migration.
In future session language versions, private keys will be migratable by default.
Parameters:
v0.3.4
key_type
: Optional. If specified, must be one of the following:P-256
: NIST P-256 EC private key (also known as secp256r1 or prime256v1). This is the default if no type was specified.P-384
: NIST P-384 EC private key (also known as secp384r1)Ed25519
: ED25519 EdDSA private keyRSA-2048
: 2048-bit RSA private keyRSA-3072
: 3072-bit RSA private key
v0.3.7
migrate
: Whether to keep the private key when updating the session. Optional, defaults tofalse
. Both old and new session must containmigrate: true
in order for migration to happen.
Examples:
secrets:
- name: my_generated_long_term_signing_key
kind: private-key
key_type: Ed25519
migrate: true
- name: my_generated_tls_server_private_key
kind: private-key
key_type: P-384
- name: my_explicit_tls_server_private_key
kind: private-key
value: |
-----BEGIN PRIVATE KEY-----
...
-----END PRIVATE KEY-----
v0.3.5
Secret Placeholders:
Since CAS v5.2.0, private keys are accessible in PEM-encoded or DER-encoded PKCS#8 format. Assume a secret named my_key
:
$$SCONE::my_key$$
or$$SCONE::my_key:pem$$
or$$SCONE::my_key:pkcs8:pem$$
- PEM-encoded PKCS#8 format$$SCONE::my_key:der$$
or$$SCONE::my_key:pkcs8:der$$
- DER-encoded PKCS#8 format
Note
Ed25519 private keys are serialized in PKCS#8 v2 format (also known as OneAsymmetricKey
, defined by RFC5958). OpenSSL, including version 1.1.1h, does not support this format.
Note
Accessing private keys directly is only possible starting at CAS v5.2.0. In older versions, private keys can only be accessed through X.509 certificates: $$SCONE::my_tls_server_certificate.key$$
x509 and x509-ca
CAS is able to generate and manage X.509v3 certificates, making it easy to construct a Public Key Infrastructure (PKI).
There are two kinds of X.509 certificates that CAS supports: End-entity and Certification Authority (CA) certificates.
Their main difference is in their capability to sign other certificates.
End-entity certificates are indicated by kind x509
, CA certificates by x509-ca
.
Explicit values must be specified in PEM encoding.
Parameters:
private_key
: Unless imported or given an explicit value, each certificate requires a private key, referencing anotherprivate-key
secret.issuer
: Optional reference to anotherx509-ca
certificate which signs this certificate. If omitted, generated certificates will be self-signed. Note that access to the issuer's private key is required for signing unless an explicit certificatevalue
is specified.common_name
: An optional certificate common name. If omitted, the firstdns
name (see below) will be used as the common name. If no DNS name has been specified, the secret'sname
will be used as the common name.endpoint
: Optional, must be eitherserver
orclient
when specified. When specified, an Extended Key Usage (EKU) extension will be added to the generated certificate. If omitted, no EKU extension will be added. Only applicable to end-entity certificates.dns
: Superseded by thesan
option since version 0.3.10! Optional DNS name or list of DNS names that will be included in the Subject Alternative Name (SAN) extension of the generated certificate. Only applicable to end-entity certificates. Cannot be used when the certificate has aclient
endpoint.valid_for
: Optional duration (e.g.:1 year
or59d
) for which generated certificates are valid. Certificates will automatically be re-generated before they expire. If omitted, generated certificates stay valid for a virtually unlimited amount of time. Not applicable to imported certificates or certificates with an explicitvalue
.
v0.3.10
san
: Optional Subject Alternative Name or list of Subject Alternative Names to be included in the SAN extension of the generated certificate. Only applicable to end-entity certificates. Each entry must have one of the following formats (note that the quotation marks are required):"dns:<DNS name>"
, e.g."dns:example.com"
"ip:<IP address>"
, e.g."ip:192.168.1.2"
or"ip:2001:db8:3333:4444:5555:6666:7777:8888"
Example:
secrets:
- name: my_ca_certificate
kind: x509-ca
private_key: my_ca_private_key
common_name: "My own CA"
- name: my_generated_server_certificate
kind: x509
private_key: my_server_certificate_private_key
issuer: my_ca_certificate
common_name: "example.com"
valid_for: 90 days
endpoint: server
san:
- "dns:example.com"
- "dns:db.example.com"
- "dns:*.api.example.com"
- "ip:192.168.1.2"
- name: my_explicit_server_certificate
kind: x509
value: |
-----BEGIN CERTIFICATE-----
MIIB0TCCAXigAwIBAgIUX4hfQWl+PKcrmOFW8phCO1vtQpUwCgYIKoZIzj0EAwIw
HzEdMBsGA1UEAwwUVGVzdCBJbnRlcm1lZGlhdGUgQ0EwIBcNMjAwNTA2MTQ1NTAx
WhgPMzAxOTA5MDcxNDU1MDFaMBYxFDASBgNVBAMMC2V4YW1wbGUuY29tMFkwEwYH
KoZIzj0CAQYIKoZIzj0DAQcDQgAE1gqmACizRH9ENwun/rkmqoCjxf6NPJNHTpYg
y8D5UOy5HNZXSi6ZNNL1x89d6UZfrYfDrf/PwH5LOhrgfkm42aOBmDCBlTAdBgNV
HQ4EFgQUw3LfMbqwEJJRr5v7itg4A5jR0ngwHwYDVR0jBBgwFoAUHgrspKzSFC8r
0/ygrsQIGA+Ft6MwDgYDVR0PAQH/BAQDAgWgMB0GA1UdJQQWMBQGCCsGAQUFBwMB
BggrBgEFBQcDAjAMBgNVHRMBAf8EAjAAMBYGA1UdEQQPMA2CC2V4YW1wbGUuY29t
MAoGCCqGSM49BAMCA0cAMEQCIAC7fWVRBG3mBzfyKf/WidYVL9IcAOdYsElgHTKb
5h5HAiBlXklXq2lXo3srdQNJ4I8QJwWMYLIZUUw7fmWKOaireg==
-----END CERTIFICATE-----
Secret Placeholders
Assume a secret named my_x509
:
v0.3.5
$$SCONE::my_x509$$
or$$SCONE::my_x509:crt$$
or$$SCONE::my_x509:crt:pem$$
- PEM-encoded certificate$$SCONE::my_x509:crt:der$$
- DER-encoded certificate$$SCONE::my_x509:privatekey$$
or$$SCONE::my_x509:privatekey:pem$$
or$$SCONE::my_x509:privatekey:pkcs8:pem$$
- PEM-encoded PKCS#8 private key. The private key must be accessible.$$SCONE::my_x509:privatekey:der$$
or$$SCONE::my_x509:privatekey:pkcs8:der$$
- DER-encoded PKCS#8 private key. The private key must be accessible.$$SCONE::my_x509:chain$$
- PEM-encoded certificate chain, starting at the first intermediate CA certificate (if present), and ending with the root CA certificate (if present). The certificate itself is not included. If the full chain is required, you can concatenate$$SCONE::my_x509:crt$$
and$$SCONE::my_x509:chain$$
.$$SCONE::my_x509:pkcs12-with-private-key$$
- DER-encoded PKCS#12 archive containing certificate, private key, and certificate chain. The certificate and private key are encrypted with the empty string ("") as password. (Supported since SCONE 5.7.0)
Note
CAS versions prior to 5.2.0 only support the following format suffixes (notice the dot instead of colon):
$$SCONE::my_x509.crt$$
- PEM-encoded certificate$$SCONE::my_x509.key$$
- PEM-encoded PKCS#8 private key$$SCONE::my_x509.chain$$
- Reverse PEM-encoded certificate chain, with the root CA certificate first (if present), followed by intermediate CA certificates, and the certificate itself last (included).
These formats are still supported by later CAS versions, but have been deprecated.
v0.3.7
aad-token
CAS can retrieve access tokens for Microsoft Azure Active Directory (AAD). While they are primarily used to import secrets from Azure Key Vault, they can also be consumed by application services.
Parameters:
tenant_id
: The ID of an AAD tenant (required)client_id
: The ID of an AAD application of the referenced AAD tenant (required)- Either of the following credentials are required:
application_secret
: A shared secret that was registered with AADprivate_key
andcertificate_thumbprint
: A PEM-encoded PKCS#8 RSA private key belonging to a certificate that was registered with AAD, and a thumbprint of this certificate that was returned during registration.
Note
The AAD application must have application API permissions to access secrets of an Azure Key Vault; for information on how to set up an Azure application for API access, see https://docs.microsoft.com/en-us/azure/storage/common/storage-auth-aad-app. The Key Vault permissions for the application must then be configured using Azure access policies or Azure role-based access control.
Example:
secrets:
- name: ad_token_1
kind: aad-token
tenant_id: e6c9c526-f1aa-4e0d-b207-50bad9a89d21
client_id: 3f6a210e-83b4-4217-9eee-4f707d8aeeb3
application_secret: "dGmbyTBE4JNAN3JJobeD"
- name: ad_token_2
kind: aad-token
tenant_id: e6c9c526-f1aa-4e0d-b207-50bad9a89d21
client_id: 3f6a210e-83b4-4217-9eee-4f707d8aeeb3
private_key: |
-----BEGIN PRIVATE KEY-----
MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQCbkIjwCh2zXbUs
...
s5is0+EmTLXoWCqftUG5RQ==
-----END PRIVATE KEY-----
certificate_thumbprint: B033DB596639F3CA02D6537055E85B8EFE060756
Secret Placeholders:
Assuming a secret named ad_token_1
, use $$SCONE::ad_token_1$$
in program arguments, environment variables or secret injection files (see Secret Injection). AAD token secrets do not support any format suffix. The token can be used to authenticate directly for Microsoft Azure services.
Note
Tokens are only valid for a limited amount of time (a couple of minutes), which means they can only be used successfully immediately after program start.
v0.3.10
config-fragment
Configuration fragments are structured values, which can be injected into other places of a session, for example the service attestation configuration. They are most useful when imported from other sessions, in order to let another session drive the security policy of this session.
Parameters:
None. Fragments require an explicit value
or must be import
ed (see secret sharing).
Example:
secrets:
- name: mrenclave_list
kind: config-fragment
value:
- ec8906f332d9aaada4c4c4ddd772bcbedb80562dd69e43ba87d80c3236914d8c
- 16bcc65040c5dd79aa93ccf465cfdde485664588acfb4f9940ef81a14a048703
- name: attestation_config_part
kind: config-fragment
value:
signer:
mrsigner: 1190831f4e21529d6702681f2906d5a27cc7cf1900bc323cd1cdedb2dc27edbd
isvprodid: 213
isvsvn_min: 13
- name: isvprodid
kind: config-fragment
import:
session: attestation_policy
secret: webserver_isvprodid
Secret Placeholders:
Assuming a secret named mrenclave_list
, use $$SCONE::mrenclave_list$$
in configuration sections that support it; for example the service attestation section:
services:
- name: loadbalancer
attestation:
- mrenclave:
- 2c4de8cbe6725f7e11f2f5240bc7e0b7fe0651f2997a48c87ca38918574ef076
- $$SCONE::mrenclave_list$$
signer:
mrsigner: ce24e0918a348837738a18c4ce7a3afe3aed8acb58ee6ddb6031a570a1e1401c
isvprodid: 6
- $$SCONE::attestation_config_part$$
Lists will be combined, i.e. the mrenclave:
list above will be expanded to
- 2c4de8cbe6725f7e11f2f5240bc7e0b7fe0651f2997a48c87ca38918574ef076
- ec8906f332d9aaada4c4c4ddd772bcbedb80562dd69e43ba87d80c3236914d8c
- 16bcc65040c5dd79aa93ccf465cfdde485664588acfb4f9940ef81a14a048703
v0.3.10
pgp-key
CAS can generate OpenPGP keys. These can be used for message encryption - for example using GPG.
Parameters:
PGP keys do not support parameters or constant values at this time.
- Generated keys have a random (non-email) user ID
- They consist of a primary EdDSA (Ed25519) signing key, and a ECDH (Curve25519) encryption subkey
- They have configured AES256, SHA256 and ZLIB as preferred encryption, hashing, and compression algorithms
Examples:
secrets:
- name: my_message_encryption_key
kind: pgp-key
Secret Placeholders:
PGP private and public keys are accessible in binary or ASCII-armored formats.
ASCII-armored keys are similar in nature to PEM-encoded PKCS#8 keys: They begin with a header like -----BEGIN PGP PRIVATE KEY BLOCK-----
, and contain a base64-encoded body.
All keys contain both the primary signing key and the encryption subkey. They are represented as version 4 signed keys of the OpenPGP specification.
Assume a secret named my_message_encryption_key
:
$$SCONE::my_message_encryption_key:privatekey:asciiarmored$$
- ASCII-armored private key (starts with-----BEGIN PGP PRIVATE KEY BLOCK-----
). Similar to the format produced bygpg --export-secret-keys --armor
$$SCONE::my_message_encryption_key:privatekey:binary$$
- Binary private key. Similar to the format produced bygpg --export-secret-keys
$$SCONE::my_message_encryption_key:privatekey:base64$$
- Base64-encoded binary private key$$SCONE::my_message_encryption_key:publickey:asciiarmored$$
- ASCII-armored public key (starts with-----BEGIN PGP PUBLIC KEY BLOCK-----
). Similar to the format produced bygpg --export --armor
$$SCONE::my_message_encryption_key:publickey:binary$$
- Binary public key. Similar to the format produced bygpg --export
$$SCONE::my_message_encryption_key:publickey:base64$$
- Base64-encoded binary public key
Secret Injection
Secrets are injected via standard means (program arguments, environment, and configuration files) into a service.
For this purpose, placeholder variables can be put into program arguments, environment variables, secret injection files, and configuration sections that support it.
These variables will be replaced with the actual secret values (be it generated or given explicitly) when the service starts.
Placeholders are of the form $$SCONE::secret_name:format_suffix$$
. The :format_suffix
is optional. Different kinds of secrets support different formats, please have a look at the previous chapter for details.
Program Arguments and Environment Variables
For example, to inject a secret into a service's program arguments its command field in the session description could look like this:
[...]
command: service_name --password $$SCONE::service_password$$ --non-confidential-argument 1234 --non-confidential-flag
[...]
In the above example, the command
's program arguments will be presented to the service with $$SCONE::service_password$$
replaced by the actual value of secret service_password
.
To inject secrets into a service's environment the session description could contain this:
[...]
environment:
FILE_ENCRYPTION_KEY: "$$SCONE::MY_SERVICES_ENCRYPTION_SECRET$$"
[...]
Note
Secrets referred to (service_private_key
and MY_SERVICES_ENCRYPTION_SECRET
in the above example) have to be defined in the secrets
section of the session description.
Secret Injection Files
A secret injection file is a file in the file system that will be updated with secrets received by the runtime from CAS. They use the same secret placeholders that can also be used in program arguments and environment variables.
For example, imagine a service configuration file containing a password. Simply writing the password into the file in cleartext would leak it - that is not an option. Using SCONE's filesystem shield to encrypt the file complicates the setup, and - if distributed as part of an image - would require users to change the encryption keys in order to protect their individual passwords. Instead, a secret injection file allows to specify a placeholder for the password, which will be dynamically replaced at runtime through the means of secret injection:
/etc/mysql/my.cnf
:
[client]
user=mysqluser
password=$$SCONE::mysqlpass$$
The path to this configuration file must be specified as part of an image (see Images). The corresponding session would look like this:
services:
- name: my_database_client
image_name: my_db_client_image
images:
- name: my_db_client_image
injection_files:
- /etc/mysql/my.cnf
Alternatively, the file's content may be specified within the session:
services:
- name: my_database_client
image_name: my_db_client_image
images:
- name: my_db_client_image
injection_files:
- path: /etc/mysql/my.cnf
content: |
[client]
user=mysqluser
password=$$SCONE::mysqlpass$$
- path: /etc/ssl/db_server_full_chain.pem
content: |
$$SCONE::db_server_cert:crt$$
$$SCONE::db_server_cert:chain$$
The content
specified in the session file can contain multiline strings.
This way, entire configuration files can be embedded in the session description, even if no secret injection is required.
Producing valid multiline strings in YAML can be challenging - https://yaml-multiline.info/ can be of great help to find the desired syntax.
Secret injection files are prepared during SCONE runtime initialization. If the file content is not provided in the session, the file at the specified path is opened, potentially through SCONE's filesystem shield, and read into memory. The secret injection is applied and the resulting file is put into SCONE's in-memory file system at the specified path. Any application requests regarding this file are served from this in-memory file system. Thus, modifications to secret injection files are NOT propagated into the file system and are NOT persistent across program invocations.
Sometimes applications demand that particular file permission are present or unset.
For example, mariadb
will ignore configuration files that are world-writable.
Secret injection files by default have 0o700 permissions.
That is they're read-, write-, and, executable by the owner, which is always the user executing the program.
If necessary different file permissions can be set in description.
In the following snippet, only the file owner is allowed read access:
injection_files:
- path: /etc/mysql/my.cnf
permission: 0o100
content: |
[client]
user=mysqluser
password=$$SCONE::mysqlpass$$
Remember that secret injection files are in-memory that don't persist data, and all modification will be lost.
v0.3.10
Dynamic Configurations
Some configuration sections, like the service attestation section, allow variable injection:
services:
- name: loadbalancer
attestation:
- mrenclave:
- 2c4de8cbe6725f7e11f2f5240bc7e0b7fe0651f2997a48c87ca38918574ef076
- bac31957ee05e5f3f95ea10632008315bf314a536a453dbb787be02c5b920b88
signer:
mrsigner: ce24e0918a348837738a18c4ce7a3afe3aed8acb58ee6ddb6031a570a1e1401c
isvprodid: 6
- $$SCONE::attestation_config_part$$
config-fragment secrets are especially useful here, since they support structured values.
ascii and other secret kinds can be used, too, except binary-encoded secrets. When using another encoding (like :hex
), binary secrets can be used as well.
Secret Sharing
Session owners can decide to share their secrets with other parties to enable collaboration. For example, database operators could use TLS to implement access control to databases. They would define an access certificate, configure the database to only allow connections from said certificate and export it to the database client:
name: database_operator
secrets:
- name: database_access_key
kind: private-key
export:
session: database_client
- name: database_access_certificate
kind: x509
private_key: database_access_key
export:
session: database_client
The secret owner might also specify multiple receiving sessions - or namespaces - at once:
name: database_operator
secrets:
- name: database_access_key
kind: private-key
export:
- session: database_client
- session: another_client
- name: database_access_certificate
kind: x509
private_key: database_access_key
export:
- session: database_client
- session: another_client
- namespace: relying_party # since v0.3.5
Furthermore, the export might be restricted to certain instances of the importing session. For more details, see the concrete SCONE ID format by which other sessions can be referenced in Referencing Other Sessions.
The database client, on the other hand, would import it and could use it in their session as if it was their own certificate:
name: database_client
secrets:
- name: database_access_certificate
kind: x509 # optional
import:
session: database_operator
secret: database_access_certificate
On the importing side, the kind
of a secret can be optionally defined to ensure imported secrets match a specific form, but this is not strictly necessary.
When importing certificates, the associated private-key
does not have to be imported explicitly - it will be available automatically if the exporting session exports the private key as well.
In very specific cases, secrets may also be made public (exported to anyone without authentication) - this may be useful when, for example, defining certificate key hashes:
name: policy_checker
secrets:
- name: certificate_hash
kind: ascii
value: "4sEY84YhUKT7Q7m4qUj2pmQMxFvZK5XpDyJ3QR6mETVRDkyren"
export_public: true
This hash can be used in another session's access control policy through secret substitution (see Access Control):
name: checked_session
secrets:
- name: policy_checker_certificate_hash
import:
session: policy_checker
secret: certificate_hash
access_policy:
read:
- "$$SCONE::policy_checker_certificate_hash$$"
Warning
By using export_public: true
, the whole world will be able to see the secret value. Make sure this is your intention.
These secrets may also be queried through the /v1/values
CAS REST API endpoint.
v0.3.7
Microsoft Azure Key Vault Import
Existing secret values can be imported from a Microsoft Azure Key Vault (AKV). This requires:
- a new
import_akv
mapping which specifies the vault to import from - an
aad-token
secret authorized to access this vault
Example:
secrets:
- name: db_encryption_key
kind: binary
import_akv:
vault: myvaultname.vault.azure.net
secret_name: abc
token: $$SCONE::db-aad-token$$
- name: db-aad-token
kind: aad-token
...
import_akv
Parameters:
vault
: The address of the key vault to use (required)secret_name
: The name of the secret that should be fetched from the vault (optional). If omitted, thename
of the secret as defined in the session will be usedtoken
: A reference to anaad-token
secret of the form$$SCONE::<secret-name>$$
. This token will be used to authenticate requests against the vault. If the session contains exactly oneaad-token
secret, the parameter is optional, and this secret will be used by default. If the session contains multipleaad-token
secrets, the parameter must be specified.
Note
import
and import_akv
are mutually exclusive.
The secret's kind
is optional and will be inferred if omitted.
Note
PEM-encoded certificates imported from a key vault will be represented as X.509 secrets.
PKCS#12-encoded certificates, on the other hand, will be represented as plain text secrets, i.e. suffixes such as :privatekey
cannot be used in secret placeholders for them.
v0.3.10
Secret Backends
By default, all session secrets are stored in the CAS database. It is possible to select another backend.
When changing the backend, secret values (including FSPF keys) will be encrypted, and stored in the backend of choice. The keys used for this encryption process, as well as freshness information will be stored in the CAS database. This means that administrators of the chosen backend, for example Azure Key Vault, cannot access the plaintext secret values. Deletion, modification or rollback of secret values will be detected by CAS. Note that this renders the session unusable, though - any session operation, including session update, will fail with an error when attempting to load missing or manipulated secret values.
It is possible to migrate existing secret values between secret backends, simply by updating the session and adding the desired secret_config
(see below).
v0.3.10
Microsoft Azure Key Vault Secret Backend
All secrets can be stored in Azure Key Vault, by configuring the secret backend in the session:
secret_config:
store_in: !akv
token: $$SCONE::my_aad_token$$
vault: https://example.vault.microsoftazure.de
Note that my_aad_token
must refer to an aad-token secret - similar to Microsoft Azure Key Vault Imports.
There are some key differences between using Azure Key Vault as a secret backend, and importing individual secrets from Azure Key Vault:
- When using Azure Key Vault as a secret backend, instead of storing them in the CAS database, all secrets managed by CAS will be stored in the form
cas-<session-hash>-<secret-tag>
in the chosen Azure Key Vault. Example secret name:cas-330dfcd96c99e735332bfb7a5dd147ddb2b9aac26486572a116a739062fea98b-9870723acbbc96d55ad7b29a015f696f
- When using Azure Key Vault as a secret backend, secret values stored in the vault will be encrypted with keys managed by CAS. Having access to the Key Vault doesn't break confidentiality of secrets stored by CAS. When importing secrets from Azure Key Vault on the other hand, secrets are stored in plaintext and vault administrators can view them.
- When using Azure Key Vault as a secret backend, secret values cannot be manually changed in the vault either. When importing secrets from Azure Key Vault on the other hand, secret values can be changed externally.
Note
When updating a session, secrets of the predecessor session will not be deleted from Azure Key Vault.
CAS Database Secret Backend
For reference, the default secret backend is the CAS database:
secret_config:
store_in: !cas
It will be used by default, if no secret_config
is present in the session.
Secret Migration
When uploading a new session which has a predecessor session, secret migration takes place. In short: Secret values which were generated as part of the old session will be kept when the new session defines a secret with the same name and compatible kind.
Secret kind | Values kept when updating session? |
---|---|
ascii | |
binary | |
private-key | only if migrate: true was set |
x509 | |
pgp-key |
Example old session:
secrets:
- name: my_generated_ascii_secret
kind: ascii
size: 12
- name: foobar
kind: binary
value: DEADBEEF
Example new session:
secrets:
- name: my_generated_ascii_secret
kind: ascii
size: 12
- name: foobar
kind: private-key
In the given example, the value of my_generated_ascii_secret
will be kept, as it stays an ASCII secret of the same size, whereas foobar
will be freshly generated, since its kind changed.
Warning
Generated private keys will only be kept if migrate: true
was set. Certificates will never be kept, they will always be re-generated when updating a session.
Secret migration also takes place when using a different session description language version (e.g. 0.2 -> 0.3)!
Volumes
Similar to Docker, the volumes
keyword allows to specify file system regions that can be mounted into the file system in addition to the regions specified by the main file system protection file of a service. Each volume has an arbitrary but unique name
. In order to grant services access to a volume, it first has to be included in an image (see section Images). Subsequently, the image can be specified for a service (see section Service Description), and all image-defined volumes will be mounted automatically.
Note
The volume name
is not the volume's mount point. The latter is defined as part of an image.
By default, a volume will be automatically initialized during the first use:
volumes:
- name: my_database
The volume will contain a single encrypted region, and a new key will be generated by CAS to encrypt volume.fspf
(the file system protection file for the volume). Once initialized, CAS and the runtime will work together to track the updates of the volume. This ensures that a volume can be initialized only once. Use of automatically initialized volumes ensures that the key for the file system is only visible inside of CAS and the application(s) that get access to this volume, i.e., no system administrator will ever see the volume key.
Alternatively, a file system protection file key (fspf_key
) and file system protection file tag (fspf_tag
) can be specified for the volume:
volumes:
- name: my_database
fspf_key: f843051d21afa9e52a5b54a708a8032bc49581e982696a81393b8da4a32d00b8
fspf_tag: 8d8fbe332fb9c893020be791ccd3e8a8
fspf_key
must be either a hex-encoded 32 byte long key, ...
v0.3.7
- ... or a reference to a compatible SCONE binary secret (
$$SCONE::<secret-name>$$
) fspf_tag
must be a hex-encoded 16 byte value
fspf_key
is the key used to encrypt the volume.fspf
and fspf_tag
describes the initial state of the volume. On each volume update (e.g., creation of a file in the region or update of an existing file), the SCONE runtime will send a new fspf_tag
to CAS to ensure integrity and freshness of the volume state.
A volume can be initialized using the SCONE CLI's scone fspf create-volume
command, which generates an encryption key, encrypts initial files, and calculates the initial tag to put into the session.
Volume Sharing
Volumes may be exported to other sessions, which implies authorizing the other sessions to decrypt and read existing files or encrypt and store new files:
volumes:
- name: my_database
export:
session: another-session
or
volumes:
- name: my_database
export:
- session: another-session
- session: foobar
session_hash: 668e9aaba22c7631bbcc89b627d77e53539bcaade9e7c2c08242f56aab272088
The concrete SCONE ID format by which other sessions can be referenced is described in section Referencing Other Sessions. Note that volumes can only be exported to local sessions on the same CAS, not to sessions on a remote CAS.
Similarly, volumes may be imported from another session (in which case fspf key/tag and export list must be omitted):
volumes:
- name: their_database
import:
session: the_exporting_session
volume: my_database
v0.3.2
Volume Tag Update Policy
When exporting a volume, it is possible to restrict which kind of modifications an importing session is allowed to perform. Section Image Volumes demonstrates how volume access can be restricted for local services; the same is also possible for volume exports by using the update_policy
key:
volumes:
- name: my_database
export:
- to:
session: web_server
session_hash: 668e9aaba22c7631bbcc89b627d77e53539bcaade9e7c2c08242f56aab272088
update_policy: ephemeral
Note that the SCONE ID (session
and session_hash
) needed to be moved to a new to:
section!
update_policy
can have any of the following values:
ephemeral
: Importing sessions may only use theephemeral
policy. This implies that they are not allowed to alter the volume's state on the CAS (please read Image Volumes for further explanation). Any tag policy specified by the importing session is ignored.rollback_protected
: This is the default setting ifupdate_policy
is omitted. Importing sessions can use either arollback_protected
or anephemeral
policy at their discretion.no_rollback_protection
: Importing sessions are allowed to use arollback_protected
,ephemeral
orno_rollback_protection
policy at their discretion. This option is dangerous, as it also allows third parties to perform rollbacks unnoticed. It should not be necessary for most use cases.
v0.3.10
Volume Alias
In multi-stakeholder processing pipelines, individual components may have only partial knowledge of the whole system. To facilitate pipeline assembly, it is possible to export a volume under a different name (called alias) towards individual sessions:
name: database_server
volumes:
- name: my_database
export:
- to:
session: processing_component_1
session_hash: 668e9aaba22c7631bbcc89b627d77e53539bcaade9e7c2c08242f56aab272088
volume_alias: output
- to:
session: processing_component_2
volume_alias: input
When importing the volume, the alias must be specified as the volume's name:
name: processing_component_2
volumes:
- name: dataset
import:
session: database_server
volume: input
During import, using the original volume name is not possible.
Images
The images
keyword allows specifying images usable by services (see section Service Description). Each image has an arbitrary but unique name
:
images:
- name: my_image
Image Volumes
Images may define access to volumes, by referencing a previously declared volume's name
and giving it a mount point (path
):
volumes:
- name: my_database
images:
- name: my_image
volumes:
- name: my_database
path: /media/database
Note
The given path must already exist in the filesystem, e.g., through a mounted docker volume. The information provided as part of the session description are only used to encrypt and authenticate all of the volume's files. The CAS does not actually store the encrypted files.
v0.3.2
Image Volume Tag Update Policy
By default, volumes are rollback-protected: Attempting to restore an old volume state and letting a service read files from or write files to this old state will be detected and prevented. In specific cases, however, this may not be the desired behavior. The update_policy
key can be used to change it:
volumes:
- name: my_database
images:
- name: my_image
volumes:
- name: my_database
path: /media/database
update_policy: no_rollback_protection
The following values are possible as a volume update_policy
policy:
rollback_protected
: This is the default setting ifupdate_policy
is omitted. Services are allowed to alter the volume state, any rollback will be detected and lead to an error upon access. This ensures a coherent, linear history of volume changes.ephemeral
: Any changes done to the volume state will be ignored by CAS. This can be useful when a volume is supposed to remain in a specific state - an initialization service could use an image with volumeupdate_policy: rollback_protected
to prepare the volume, and all other services can useupdate_policy: ephemeral
in order to ignore further modifications. Note that this does not prevent services from modifying files and directories in the volume's path! This will still work as long as the service is running. Once it is restarted, however, CAS will detect the modification and refuse any access to the modified volume. Therefore, if you expect services to make changes to the volume, it is a good idea to back up the initialized volume, and restore this backup once the service is stopped. This ensures that new instances of the service are able to access the volume in its expected state.no_rollback_protection
: Services are allowed to alter the volume's state and rollback prevention checks are disabled. This option is dangerous, as it also allows third parties to perform rollbacks unnoticed. It should not be necessary for most use cases.
Note
When using an imported volume, the exporting session may have applied restrictions on the volume's update_policy
.
Attempting to use an unauthorized update_policy
will lead to errors upon volume access.
For details, please refer to section Volume Sharing.
Image Secret Injection Files
Images may also contain secret injection files, a way to inject secrets into configuration files:
images:
- name: proxy_image
injection_files:
- /etc/nginx/nginx.conf
- path: /etc/mysql/my.cnf
content: |
[client]
user=mysqluser
password=$$SCONE::mysqlpass$$
For details, refer to section Secret Injection Files.
Access Control
Any operation on a session description requires permission. If the entity requesting a certain operation is not explicitly permitted to perform said operation, the request will fail. The access_policy
keyword allows specifying lists of entities that are allowed to perform the following operations:
read
: permit to read the session description - without the secrets generated by CASupdate
: permit to update the session
v0.3.5
create_sessions
: Create new sessions in the namespace of this session. If omitted, all entities listed underupdate
will be able to create sessions.
Granting permission to a certain entity to perform one of these operations involves adding their client certificate public key to the list of authorized entities.
A certificate with this key shall be used when establishing a connection to CAS (see API Documentation, Authentication section). TLS ensures that the client is in possession of the corresponding private key.
CAS uses key-based authentication instead of whole certificate authentication to ensure that certificates can be renewed without problems - otherwise, users could be locked out of the session when their certificate expires.
When using the scone CLI, the user certificate can be shown by running scone self show
.
Beside public certificates, the following values can be used:
- Public key hash of a certificate. This hash can be calculated by using the SCONE CLI:
scone self show
shows the hash of the CLI client identity,scone cert show-key-hash "path_to_certificate_file_in_pem_format"
shows the key hash for any certificate file. A valid hash looks similar to:3s1pm8W6Be6cxvAQRbRP5YXd9YuERAr7KswN97uGtoPkRW87x1
CREATOR
keyword: permit access to the creator of the policy: this is the public key of the TLS client certificate used when creating this sessionANY
keyword: permit access to any entity. IfANY
is specified, there must be no other entries in the list for this operationNONE
keyword: deny all requests for a particular operation. IfNONE
is specified, there must be no other entries in the list for this operation$$SCONE::secret-name$$
will dynamically use the value of a secret with the given name (secret-name
) at permission evaluation time. The replaced value must be eitherCREATOR
(ascii), a certificate key hash (ascii) or certificate (x509) as defined above. It is possible to use explicit secrets, generated secrets, and imported secrets. When referencing X.509 certificates, do not specify a format suffix. If the mentioned secret does not exist, cannot be read, or has an incompatible value, it will be ignored, but an error message will be shown on unsuccessful authentication attempts.-
signer: <public key>
: Public key of a session signer. Signing sessions is an alternative to using TLS client certificates during session upload.scone self show-session-signing-key
shows the CLI signer identity. The public key is an X.509 Subject Public Key Info (SPKI, see RFC 5280 section 4.1.2.7) encoded. At the moment, Ed25519 and P384/secp384r1 keys are supported. A valid public key looks similar to:
Note that signers are not supported in the-----BEGIN PUBLIC KEY----- MCowBQYDK2VwAyEAOsufQ7RCOXueVLQBpk7Y44GAaj+LzPbmHfdr/TPdlrE= -----END PUBLIC KEY-----
read
policy. -
require-all:
orrequire-at-least-X:
- Please refer to governance
By default, the access policy is defined as follows:
access_policy:
read:
- CREATOR
update:
- CREATOR
create_sessions:
<same as update>
Default values will be used for operations not explicitly specified in a session description.
Example policy:
access_policy:
read:
- CREATOR
- 3s1pm8W6Be6cxvAQRbRP5YXd9YuERAr7KswN97uGtoPkRW87x1
- |
-----BEGIN CERTIFICATE-----
MIIFwTCCA6mgAwIBAgIUCF1MVJJ78BIf4WmTE24aAX7NlHowDQYJKoZIhvcNAQEL
BQAwcDELMAkGA1UEBhMCVVMxDzANBgNVBAgMBk9yZWdvbjERMA8GA1UEBwwIUG9y
dGxhbmQxFTATBgNVBAoMDENvbXBhbnkgTmFtZTEMMAoGA1UECwwDT3JnMRgwFgYD
VQQDDA93d3cuZXhhbXBsZS5jb20wHhcNMTkwNzIyMTU1NTExWhcNMTkwODIyMTU1
NTExWjBwMQswCQYDVQQGEwJVUzEPMA0GA1UECAwGT3JlZ29uMREwDwYDVQQHDAhQ
b3J0bGFuZDEVMBMGA1UECgwMQ29tcGFueSBOYW1lMQwwCgYDVQQLDANPcmcxGDAW
BgNVBAMMD3d3dy5leGFtcGxlLmNvbTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCC
AgoCggIBALVbVIrBAlzDOztWs9hZr5kvYoUwq/hL7zaMrYKBLQJZFNbhmMaUsW7A
Fzj87dzP3xIf4c2r3IGJSukv7hJpaJ2Ykv80i3C7EiFgaDV/+JP9d/GjsvcW20zH
mtJcBIkdkqPt1epOtxsMyJGZL+34DoWOqgY7up6nCirr+MeUxYJ/dWBFD1j0iuHl
Y+rEMsv4xFBndgLmMQNlcMyXtBgPls4EgnDfnjICqIYMHt6PG+kwoR4tbs+v2Gsl
vqldxI7efErZh+kKtjtFxt6qzrypUs9bYgH3tsaUE0xYeK/A2llylJzPOv6vkCqg
vPOJETcZyoeH46niITdPssYr4yPQOxn/a7WS+7Mn2y6o5z4Q+DkB96lzUyvVJnwO
aorzec0PaB/qqYrHqVfftMu4thMwHGB8CrGUiq/ImHPWkfobyVcMYJ0/LaLSDHFj
1hN36VkzWqQcCM6ymhjx9Lpfzzxna5910jE86zb1cMnD/eAAd90jpJvGJN43Hw40
MIvjYBunOy9P3ah0kgCk7gW0oKlYHxugv8pZVHMwU1HFIdwYvlGd09XHFDyj9tul
eX8zaVwaNeLUrMdJN5Ct1HX16RpnpaIMwwExzXgsZ01BQcfIcGWGbvBfH2C86klt
SuG7M6kxk4XgIIlwTSGk7qJlfd4s8PD1fVJNKvJZwXXoQBy4hCrTAgMBAAGjUzBR
MB0GA1UdDgQWBBRSUKop9QDGmSdLCfzWlBIF5ClNVDAfBgNVHSMEGDAWgBRSUKop
9QDGmSdLCfzWlBIF5ClNVDAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEBCwUA
A4ICAQAny4QmzvCza0TQUuh7YIxtkBjJoyTSDGmr5W/4AWKsoZJM9QxzWeIAXhWD
UPH2TfwcNX/ovZiSDQaGduRL67Wk8lbp1MvjACMEtLRjsbnYtGFdhit0fR97B5Y6
d06Ka/NXgPTJorXx8WSWUp0qaAQcgvhfgF0vnOSB5CbP5RSYE5TuLu6gh+iQTrBI
Syl+9UaopkbQDRsg+XRfie+kUxQgldUAFvFmu6sM6FTbw0KGkrsOajwpF/Fu5hSV
Ucov4Lzrrxkok5FzWPkVtMalLZ4Du+ZUYG//10WZg+HdrIwx3m2wxrFIkZaMKxv4
ZkIMsb6DUPUZqy8qZpMzIqvDzx3iYEWWfBOCJWBjs8/V1mAuUu6TBCKAJpvfX6bU
hNrCbnrpuxuCCPJnj9sXkBDvl5rcyfshTtKl3NoBrRRDuUHWsJWzsKvBQtwN46vF
CbF0aXOozihtmmcMpFFeDIj6p/5qlaJtslegtfv2zoztc3e2ituOjqFQ/I5pplvo
p8EGwCI1xTGF0BTatcSV1+lLNeONhhAtwliV13nPSH1o4yxoZ+xZTZq4+9ylw7dq
yV3BQM11U6OyAPE1G6EX0PgFvLm25sGTJq9TKXs9yWPRit9vHcOCXSGn8osn4SMg
Puqpk+3M9xR8XDPJiBjkxcSnt9+EDNwpthTzgUEoyM6dY8nvWA==
-----END CERTIFICATE-----
- "$$SCONE::remote_validation_service$$"
update:
- signer: |
-----BEGIN PUBLIC KEY-----
MCowBQYDK2VwAyEAOsufQ7RCOXueVLQBpk7Y44GAaj+LzPbmHfdr/TPdlrE=
-----END PUBLIC KEY-----
create_sessions:
- NONE
This policy will allow read requests from the creator, a user whose TLS client certificate has a public key hash 3s1pm8W6Be6cxvAQRbRP5YXd9YuERAr7KswN97uGtoPkRW87x1
, a user whose TLS client certificate has a public key similar to the one of the certificate specified in the session description and a user whose credential is taken from the secret named remote_validation_service
(which may be imported from another session).
The session may only be updated if successors are signed by the given signer identity:
-----BEGIN PUBLIC KEY-----
MCowBQYDK2VwAyEAOsufQ7RCOXueVLQBpk7Y44GAaj+LzPbmHfdr/TPdlrE=
-----END PUBLIC KEY-----
No one is allowed to create sessions in its namespace.
v0.3.10
Individual sections or the entire access_policy can be replaced with variables, too:
access_policy: $$SCONE::external_policy$$
access_policy:
update: $$SCONE::external_update_policy$$
Warning
Make sure that referenced secrets are valid and stay valid over the course of the session's lifetime, otherwise you may lose access to your session.
Note
When an imported access policy (fragment) contains CREATOR
, the reference is evaluated in the context of the importing session, i.e. the creator of the importing session is being authorized.
v0.3.10
Governance
For multi-stakeholder computations, controlling access to a session with a single credential is insufficient.
The governance system allows multi-credential access control using require-all
and require-at-least-X
rules.
Example:
access_policy:
read: NONE
update:
require-all:
- require-at-least-2:
- signer: $voter1
- signer: $voter2
- signer: $voter3
- require-all:
- signer: $veto_member1
- signer: $veto_member2
The above example requires an update to a session to be signed by both $veto_member1
and $veto_member2
, as well as at least 2 of the 3 $voter
s.
Governance rules can be used in the update
and create_sessions
access policies, but not in the read
access policy.
Note
require-all
and require-at-least-X
rules are designed to be used with signer
s.
While it is possible to specify certificates or certificate key hashes, remember that a session can be created either using exactly one TLS client certificate, or one or more signatures.
Therefore, it does not make sense to require more than one certificate at a time.
Rules can be arbitrarily deeply nested. Extended example:
access_policy:
read: NONE
update:
require-at-least-1:
- signer: $owner
- require-all:
- require-at-least-2:
- signer: $voter1
- signer: $voter2
- signer: $voter3
- require-all:
- signer: $veto_member1
- signer: $veto_member2
This example works the same as the previous one, but additionally allows the $owner
to overrule all other members.
Attestation Security
The services' security directly depends on CAS' ability to verify that a service process has not been manipulated (referred to as attestation), as described in the service attestation section. CAS ships with secure defaults, and only allows hardware-attested services running on trustworthy platforms in secure production-mode enclaves.
v0.3.9
Singleton Enclaves
SCONE Singleton Enclaves ensures that each enclave is uniquely identifiable via attestation mitigating attacks in which the adversary exploits the enclave before it connects to CAS. Typically enclaves containing the same software can not be distinguished via attestation making it impossible to ensure the freshness of an enclave, i.e., ensuring that the enclave has not been used before. Therefore an adversary that is able to control the enclave could load code that pretends to be a fresh enclave and illegitimately obtain secrets from CAS. With SCONE Singleton Enclaves, CAS is able to verify each enclave's freshness, essentially mitigating these kinds of attacks.
Whether this protection is necessary is application dependent.
For most applications such an attack requires a severe security vulnerability the adversary is able to exploit.
However, if the application loads code dynamically, which must be explicitly allowed by setting SCONE_ALLOW_DLOPEN
in SCONE, contains a code interpreter, such as Python, Java, Ruby, JavaScript, etc, or compiles code just in time (JIT) it is much easier to exploit.
For such applications we strongly recommend using singleton enclaves.
If in doubt, we suggest you activate the feature as it has only very little negative effects: * Enclaves require a bit longer to start on current hardware (in the order of 100 ms), and * SGX-derived seal keys are not consistent across enclave restarts (the corresponding SCONE interface to fetch seal keys will be disabled). Thou, such keys can easily be replaced with keys managed by CAS as shown in above in the #[Secrets] section. * Lastly, singleton enclaves are currently incompatible with vault files and fork support.
Note that, in production environments, Singleton Enclaves currently require hardware with FLC (Flexible Launch Control) support. FLC was introduced in 2018 (An update on 3rd Party Attestation) by Intel and most modern Processors should support it.
Singleton enclave support was added in SCONE 5.7.0 and can be opted in with the following option in security
:
security:
singleton_enclaves: true
Singleton enclaves will be enabled by default starting with the next session language version.
v0.3.1
Tolerating Hardware Attestation Issues
Sometimes it may be necessary to relax the secure defaults, for instance, when:
- Services should run in a testing environment for debugging purposes
- A trade-off is being made between security and performance, like enabling Hyper-Threading (which opens an Information Disclosure Side Channel)
- A platform with known security vulnerabilities is used in a testing environment
Example:
security:
attestation:
tolerate: [debug-mode, hyperthreading]
tolerate
is an array which can hold the following variants:
debug-mode
enclaves allow introspection with a debugger. This disables enclave protection, all secrets can be extracted.hyperthreading
: Enabled Hyper-Threading opens a Microarchitectural Data Sampling Information Disclosure Side Channel on Intel SGX platforms. If the performance penalty can be tolerated, disabling Hyper-Threading instead of ignoring the issue may be viable. See https://www.intel.com/content/www/us/en/security-center/advisory/intel-sa-00233.htmlinsecure-igpu
: An enabled integrated GPU could be exploited to disclose information on Intel SGX platforms. If not required for operation, disable the IGPU instead of tolerating this issue. See https://www.intel.com/content/www/us/en/security-center/advisory/intel-sa-00219.htmlsoftware-hardening-needed
: The service program needs to be re-compiled with different compiler settings to protect against exploits. This is a category for a collection of Intel SGX advisories, which need to be specified separately (see below).aepic-leak
: The platform is vulnerable to AEPIC Leak, which can be used to disclose information. See https://www.intel.com/content/www/us/en/security-center/advisory/intel-sa-00657.html and https://aepicleak.cominsecure-configuration
: The platform needs to be reconfigured to protect against certain kinds of attacks. This is a category for a collection of Intel SGX advisories, which need to be specified separately (see below).outdated-tcb
: The Trusted Computing Base (TCB) of the platform, i.e. firmware or microcode, needs to be updated due to security flaws. This is a category for a collection of Intel SGX advisories, which need to be specified separately (see below).
When running a service on a platform that is affected by one of the above problems, attestation will fail with an error, unless they have been specified in the tolerate
list. The error message will contain instructions on how to change attestation security settings in order to ignore the specific problems.
Note
Instead of ignoring platform security issues, solving them should always be preferred. Often, this involves updating the platform's firmware or CPU microcode. Sometimes, it can be necessary to change BIOS/UEFI settings or recompile the service with different settings. The error message as well as linked Intel advisories contain more details.
Warning
Displayed attestation error messages are not authenticated, and may be forged by a MitM attacker. It is advisable to critically review the suggested configuration changes as well as Intel advisories.
Intel will release advisories when becoming aware of new security issues with SGX-enabled processors. Some of the problems listed in these advisories are encountered more frequently, in which case SCONE/CAS provide shortcuts to ignore them (like hyperthreading
). Others may be more severe or very recent. In order to ignore them, they and their associated category (software-hardening-needed
/ insecure-configuration
/ outdated-tcb
) need to be specified explicitly. Example:
security:
attestation:
tolerate: [outdated-tcb]
ignore_advisories: [INTEL-SA-00161, INTEL-SA-00270]
When in debug-mode
, all advisories can be ignored by using a wildcard, simplifying the workflow in testing environments:
security:
attestation:
tolerate: [debug-mode, outdated-tcb]
ignore_advisories: "*"
As this silently ignores newly released platform advisories too, wildcards cannot be used in (non-debug) production mode.
v0.3.1
Trusted SCONE Quoting Enclaves
By default, the system uses the SCONE attestation scheme. This scheme is built around a separate quoting enclave (QE), into which trust has to be established. This is done automatically using EPID-based attestation for a set of known trustworthy QE measurements embedded into the CAS software.
If EPID-based attestation is not available, or you want to use custom QEs, the QE public keys can be manually specified as trustworthy:
security:
attestation:
trusted_scone_qe_pubkeys: ["E37F149AE30896E314A2859874C5A9C7803FB3187B99F5D08E526B1C0396507C"]
The QE public key can be found in the log output of the Local Attestation Service (LAS). Specified keys are an additional trust anchor, and do not replace the trusted built-in QE measurements. To trust the given keys exclusively, additionally enable platform-based attestation for individual services.
v0.3.7
Microsoft Azure Attestation
Services running on the Microsoft Azure cloud computing platform may optionally be attested using Microsoft Azure Attestation (MAA). With the default hardware attestation mode, APIs provided by the hardware vendor (Intel) will be used to determine trustworthiness of the platform. When enabling MAA, an API provided by Microsoft will be used instead. In addition, MAA allows setting up Azure attestation policies, which can be managed independently of SCONE policies. Note that these policies do not replace the policies defined in the session (including, for example, MRENCLAVE values or debug mode), a service must match both policies in order to be attested successfully. In particular, this allows using one of the shared attestation providers for which no specific Azure attestation policy can be configured - all services remain protected by the SCONE attestation policy.
Note
- MAA is only available for services running on the Azure platform. Attempting to attest services running on a different platform using MAA will fail.
- Only SGX TEEs are supported, TPM attestation is not supported at the moment.
- Using MAA is optional - services running on an Azure platform can also be attested using the default hardware attestation mode.
Example MAA configuration:
security:
attestation:
mode: maa
url: https://sharedweu.weu.attest.azure.net
tolerate: [debug, maa-managed-tcb]
The following attestation parameters are supported:
mode: maa
enables MAA-based attestation and disables the default hardware attestation mode.url
points to the MAA service provider to be used (required). This can be one of the shared attestation providers or a custom one. It must be of the formhttps://<tenant>.<region>.attest.azure.net/
certificates
is an optional list of trusted (CA) certificate used to authenticate the MAA service. If omitted, a set of default Microsoft Azure TLS Issuing CAs will be used. MAA produces tokens, whose signatures will be verified against keys acquired from an OpenID metadata endpoint (<url>/certs
). The connection to this endpoint will be secured with TLS, authenticated by the configured trustedcertificates
.min_rsa_signing_key_size
determines the minimum size of RSA signing keys that will be allowed to sign MAA tokens, in bits (optional). If omitted, only keys with 2048 bits (or longer) will be accepted. At the time of writing, Microsoft uses 2048 bit long keys in all Azure regions. Since SCONE 5.8.0, this option was deprecated and has no effect anymore
Note
Within the tolerate
section, maa-managed-tcb
must be set when using MAA.
At the moment, MAA does not expose the security posture of the platform's TCB itself, and it therefore cannot be verified using a SCONE policy. This implies that tolerating security vulnerabilities of the platform is managed at the discretion of the MAA service itself. If strict control over the platform's security status is required, the default hardware attestation mode may be more suitable.
v0.3.1
Disabling attestation
Attestation can be completely disabled:
security:
attestation:
mode: none # Default mode is 'hardware'
This may be useful in testing environments where no hardware-based attestation is available.
Warning
Disabling attestation implies that there is no service authentication being performed at all (unless a second factor is configured). Everybody with access to CAS can access all secrets of all of this session's services.
v0.3.9
2FA with Service Access Tokens
Sessions support Two-factor Authentication (2FA) using shared secrets, called Service Access Tokens. This feature offers an additional layer of authentication on top of service attestation.
Info
Service Access Tokens were added in SCONE 5.7.0.
To enable the feature, add a Service Access Token to the session's security configuration:
security:
service_access_token: j765WyMWTKksiqWbBuuc
There are no restrictions regarding the length or content of the token, however we recommend that the token should be a randomly generated password of sufficient length with high entropy.
Once enabled, the SCONE_SERVICE_ACCESS_TOKEN
environment variable must be set when starting one of the session's services.
For the above configuration example, this would be: SCONE_SERVICE_ACCESS_TOKEN=j765WyMWTKksiqWbBuuc
Service Access Tokens are used for bidirectional authentication - CAS will only provision secrets to a service enclave with the correct SCONE_SERVICE_ACCESS_TOKEN
set, and the service enclave will only accept secrets from a CAS with the correct service_access_token
in its session.
Use cases for Service Access Tokens could be:
- Defense in Depth. The additional factor provides another layer of security, complementing attestation.
- Platform Identification. Restrict which machines can run a service by provisioning the
SCONE_SERVICE_ACCESS_TOKEN
environment variable to nodes in a designated cluster. - Testing without Attestation. When attestation is disabled, access tokens provide a way to authenticate services (even when running SCONE in simulation mode). This does not ensure a trusted execution environment, however. Since the
SCONE_SERVICE_ACCESS_TOKEN
environment variable will be accessible by orchestrators and cloud service providers, we do not recommend relying on access tokens alone, without attestation.
Note
Service Access Tokens are visible when reading a session (read
access policy)
v0.3.8
2FA with Time-based One-time Passwords
Warning
This feature is experimental! Its syntax and usage may change in the future. This will not be considered a breaking change.
Sessions support Two-factor Authentication (2FA) with One-time Passwords (OTP) generated by the Time-based One-time Password Algorithm (TOTP). This feature offers an additional layer of authentication on top of attestation. Hence, OTPs can be used to authenticate individual service executions from a session during attestation. Its implementation adheres to RFC6238. The implementation generates OTP values with the length of six digits and uses a time-step of 30 seconds.
To enable the 2FA, a RFC4648 base32 encoded shared secret must be specified in the session security attestation subsection. This shared secret must have a length of at least 128 bits:
security:
attestation:
one_time_password_shared_secret: BASE32SECRET3232BASE32SECRET3232
To authenticate the execution of a service of a 2FA-enabled session, an OTP value must be generated using the TOTP with the supplied shared secret. The generated OTP value must then be appended to the SCONE_CONFIG_ID
delimited with an @
when the service is executed:
SCONE_CONFIG_ID=my-session/my-service@123456 /app/my-service
The service attestation will only commence once the CAS has verified the given OTP.
v0.3.10
The OTP shared secret can also be a reference to another secret in the session:
security:
attestation:
one_time_password_shared_secret: $$SCONE::otp_shared_secret:base32nopad$$
secrets:
- name: otp_shared_secret
kind: binary
import:
session: otp_policy
secret: otp_shared_secret
The referenced secret must either be a RFC4648 base32-encoded ascii value, or a binary secret with a size of at least 16. When using a binary secret, make sure to specify the :base32nopad
format suffix.
v0.3.10
Shared secrets can also be set on a per-service basis:
services:
- name: my-service
one_time_password_shared_secret: BASE32SECRET3232BASE32SECRET3232
If a shared secret was configured both in the services
section as well as the security
section, the one taken from services
takes precedence.
v0.3.10
Delegating Security Decisions to Other Sessions
Parts of, or even the entire security
section can be replaced with a SCONE variable. The referenced secret can be a configuration fragment imported from another session. This allows delegation of security decisions to other (administrative) sessions.
security:
attestation: $$SCONE::central_attestation_policy$$
secrets:
- name: central_attestation_policy
kind: config-fragment
import:
session: admin_session
secret: attestation_policy
Referencing Other Sessions
In some cases it may be necessary to reference other sessions, e.g. when exporting or importing volumes or secrets. This is possible by using a SCONE ID. The following sections describe the format and content of this ID.
Local CAS Sessions
Referencing another session on the same CAS is simple:
session: <session name>
- e.g.session: my-database
v0.3.5
- Pointing to sessions in a namespace:
session: <namespace name>/<session name>
v0.3.10
- Pointing to sessions in the same namespace as the current session using a relative path:
session: ../<sibling session name>
(it is also possible to go up multiple levels of namespaces:session: ../../../<session name>
) (added in SCONE 5.8.0)
v0.3.10
- Pointing to sessions nested in the current session:
session: ./<nested session name>
(added in SCONE 5.8.0)
Note that, depending on the context, you may also have to supply a secret, volume or service name, e.g.:
session: my-database
secret: db-encryption-key
By using this simple form, you trust the session's owner, and accept that their session configuration may change over time. If you want to trust a specific session configuration instead, you have to additionally specify a session hash:
session: <session name>
session_hash: <session hash-key>
e.g.:
session: my-database
session_hash: a51c14dd7029d2ef54a50a9e26efcdd37c4971b5b62cb6d244c9216f80b6eadf
Exporting/Importing elements to/from the other session will be prevented by the CAS when the currently active session does not match the specified hash. Note that, in this case, your own session may cease working when importing secrets or volumes from another session whose hash has changed, requiring you to update the session.
v0.3.6
When exporting secrets to another session, access is only granted to this specific session, excluding nested sessions. Exporting to all nested sessions is possible using the namespace
keyword (instead of session
):
namespace: <session name>
The namespace session itself can access the secret as well. Relative paths are usable, too. Note that it is not possible to restrict session hashes when exporting to a namespace. Exporting to a namespace is currently only possible for secrets, not for volumes.
Sessions on another CAS
Referencing sessions on another CAS requires more information - the remote CAS' address and a key to authenticate it:
cas_url: <CAS address>
cas_key: <CAS key hash>
session: <session name>
e.g.:
cas_url: cas.example.com
cas_key: 46YyxrywJ8PFRruWX8YLxa9q4axxYJgTbA81tv7NBcJfn43DQt
session: company-storage
The cas_key
is used for authentication and ensures that exports/imports will only be performed to/from the correct CAS.
It is of utmost importance to specify a verified, correct key.
When a CAS was attested using the CLI, you can query its verified key by using scone cas show-identification -c
.
Similarly, when attesting a CAS, you can supply the key received from another session's owner by using scone cas attest -c <CAS key hash>
.
By using cas_key
, you trust the remote CAS' owner and allow them to perform software updates without further confirmation.
Most of the time, this is an adequate solution.
In specific cases, when trusting the remote CAS' owner is not an option, it may be necessary to pin a specific CAS software revision instead.
This may be done by using the cas_software_key
instead of a cas_key
:
cas_url: <CAS address>
cas_software_key: <CAS key hash>
session: <session name>
e.g.:
cas_url: cas.example.com
cas_software_key: 3AC5RSbL73aVVf98m2UMTN2BFsQv6eQufi5BGBxrG8awxP4ygQ
session: my-namespace/company-storage
In this case, exporting/importing elements to/from the other session will be prevented by the local CAS when the software of the remote CAS changes.
The same limitations as specified for the usage of a session_hash
apply here as well.
The software key can be retrieved or specified on the CLI by using scone cas show-identification -s
and scone cas attest -s <CAS software key hash>
respectively.
URL short form
Instead of using YAML syntax, you can also fit all SCONE ID fields on a single line, forming a SCONE URL.
For instance,
cas_url: cas.example.com
cas_software_key: 3AC5RSbL73aVVf98m2UMTN2BFsQv6eQufi5BGBxrG8awxP4ygQ
session: company-storage
can also be written as
cas.example.com/cas_software_key=3AC5RSbL73aVVf98m2UMTN2BFsQv6eQufi5BGBxrG8awxP4ygQ,session=company-storage
This may be useful when referencing the same CAS multiple times, as the CAS URL and keys can be extracted into a common variable, example:
export:
- $OTHER_CAS,session=A
- $OTHER_CAS,session=B
- $OTHER_CAS,session=C
For replacing the variable with a concrete value, please refer to the SCONE CLI documentation.
The same format can also be used when referencing sessions on the local CAS. Simply omit the host and keys (but notice the leading slash /
):
/session=company-storage,session_hash=a51c14dd7029d2ef54a50a9e26efcdd37c4971b5b62cb6d244c9216f80b6eadf
Note
Relative paths (session or namespace names starting with ../
or ./
) cannot be used together with the URL short form.
v0.3.8
Host Program Arguments and Environment Variables
Warning
This feature works only with SCONE version 5.6.0 and higher.
In 5.6.0 we added a capability to use some of the host
argv if
that was specified in the session. Or in other words, one can mix
secure and insecure
variables in secure manner. That allows us to use variables values which are only know at
runtime and can not be specified in secure session.
Host Program Arguments (argv)
To use program arguments that could be specified by the operator the session file
has to contain @@#position of the argument in host argv
. For example in session:
command: ./print-arg-env arg1 @@1 @@2
Then during the execution operator will specify 2 missing arguments:
$host ./print-arg-env arg2 arg3
Which will give us the following result:
./print-arg-env arg1 arg2 arg3
If an operator does not specify all arguments anticipated by a session this will
lead to a fatal error. Because this will imply access beyond host argc
, which is
unsafe. Also, duplicate positions (for example @@1 @@1) is a fatal error.
Host Environment Variables
The same idea was applied to environment variables.
Session has to contain \@\@HOST_NAME
, like:
environment:
\@\@NAME: SESSION_VALUE
Value specified in the session will be ignored.
An operator has to define the environment variable NAME=VALUE
. And this host
variable will be used by the runtime. If a host does not have variable anticipated by a
session, we will define it empty NAME=
and leave it to an application to handle.