> ## Documentation Index
> Fetch the complete documentation index at: https://docs.tinfoil.sh/llms.txt
> Use this file to discover all available pages before exploring further.

# Attested keys

> Generate keys inside a secure enclave, grant them to containers, and verify their public keys through attestation.

Attested keys let an application use a key pair generated inside the secure enclave. Your measured configuration declares each key and the container that receives it. Attestation endorses the public key so clients can verify it and bind a protocol to it.

Use this to add attestation-backed key distribution to a protocol. [Attested SSH](/containers/attested-ssh) is the built-in example.

Requires `cvm-version` 0.14.10 or later.

## Declare and grant keys

Add `attested-keys` to your `tinfoil-config.yml` and reference each key under its container's `keys` field. This example shows the relevant fields of an existing configuration:

```yaml theme={"dark"}
cvm-version: "0.14.10"

attested-keys:
  - id: app-signing
    key: ed25519

containers:
  - name: app
    # Keep your image and other container settings here.
    keys: [app-signing]
```

| `key`        | Algorithm      | Use                        |
| ------------ | -------------- | -------------------------- |
| `ecdsa-p256` | ECDSA on P-256 | Signing                    |
| `ed25519`    | Ed25519        | Signing                    |
| `x25519`     | X25519         | Key agreement; cannot sign |

Declare up to 32 keys. Each must be granted to exactly one container. IDs start with a lowercase letter and contain lowercase letters, digits, and hyphens, up to 63 characters. `tls` and `hpke` are reserved.

Optional `uid` and `gid` set numeric file ownership. Both default to `0` and accept values from `0` to `65534`. Choose an owner that lets your application read the private key.

## Use the key files

The container receives a read-only directory at `/run/tinfoil/keys/<id>/`:

| File              | Encoding                        | Permissions |
| ----------------- | ------------------------------- | ----------- |
| `private_key.pem` | Unencrypted PKCS#8 PEM          | `0600`      |
| `public_key.pem`  | SubjectPublicKeyInfo (SPKI) PEM | `0644`      |

Your application loads these files or converts them into its protocol's required format, preserving the same key pair. Key generation does not configure the application or expose a network port.

Do not declare mounts that cover the key directory. A parent `/run` tmpfs is supported.

The granted application can read and copy its private key, so its handling of that key is part of the workload you trust. A container with `cvm_admin: true` has authority over the entire enclave, including other containers' keys.

## Verify the public key

The public key appears in the verified attestation document's `crypto_material` section with:

* `id`: the declared key ID.
* `format`: `https://tinfoil.sh/key/spki/v1`.
* `data`: the full SPKI DER public key encoded as lowercase hexadecimal.

Private key bytes are never included in attestation. Clients must verify the attestation against the expected workload before trusting an entry, then authenticate the application connection with that public key.

In the Go SDK, retrieve the entry from a verified result with `CryptoMaterialData(id, envelope.KeySPKIV1Format)`. The application parses the public key and checks that its algorithm is suitable for the protocol.

## Key lifetime

Keys are generated before containers start and remain the same across container or attestation-service restarts within that enclave boot. A full enclave reboot or relaunch generates new keys.

Clients that pin a key must verify fresh attestation before replacing it after a reboot.
