Secrets
How secrets work in SikkerKey, the types available, and the operations that apply to them.
A secret is an encrypted value stored inside a project. API keys, database passwords, connection strings, signing keys, OAuth tokens, anything that fits in a string.
Each secret has its own random AES-256-GCM data key, wrapped by the project's master key. The secret's ID is bound to the ciphertext as Additional Authenticated Data, so an encrypted blob from one secret cannot be swapped into another secret's record.
This page covers the operations that apply to every secret. The variants below add features on top.
Secret types
| Type | When to use it | Reference |
|---|---|---|
| Standard | A single string value: API key, password, connection URL, anything flat. | This page |
| Structured | Multiple related fields you want to fetch individually (host, port, username, password). | Structured Secrets |
| Managed | Database credentials SikkerKey rotates and pushes to your database for you. | Managed Secrets |
| Leased | On-demand database credentials, minted per machine, that expire and revoke on their own. | Leased Credentials |
| TTL | One-time share links with a configurable expiry, for human-to-human credential handoff. | TTL Secrets |
| Canary | A fake credential that does nothing except trip a silent alarm when accessed. | Canary Secrets |
Secret IDs
Every secret has a unique ID in the format sk_ followed by 10 random alphanumeric characters (e.g. sk_1b13qr1sb2). The ID is what you reference in the SDK, the CLI, machine grants, and access policies.
Creating a secret
From your project's Secrets page, click the + button in the top-right corner of the table and pick a type. Enter a name and a value. Optionally add a note for context.
Reading a secret
Secrets are read by authenticated machines via the SDK or CLI. The dashboard never displays decrypted values.
val apiKey = sk.getSecret("sk_stripe_key")
apiKey, err := sk.GetSecret("sk_stripe_key")
api_key = sk.get_secret("sk_stripe_key")
sikkerkey get sk_stripe_key
Replacing a value
Click the Configure button () on a secret to open the Configure Secret interface. In its Replace value section, enter the new value, type the secret's ID to confirm, and click Replace value. Replacing a value:
- Encrypts with a new random data key
- Increments the version number
- Saves the previous version to version history
Machines receive the new value on their next read.
Rotating a value
The same Configure Secret interface has a Rotate section that generates a new random value server-side. Set the length and charset, then click Rotate now.
| Charset | Output |
|---|---|
symbols (default) | Letters, digits, and ASCII special characters |
alphanumeric | Letters and digits |
numbers | Digits only |
uuid | A random UUIDv4 |
The symbols charset uses the full set of printable special characters:
!@#$%^&*()-_=+[]{}|;:,.<>?
Every rotation creates a new version and writes a secret_rotate entry to the audit log.
Automatic rotation
When creating a secret, check Enable automatic rotation to have SikkerKey generate a new value on a schedule.
- The value is auto-generated; you do not provide one
- Interval: minimum 5 minutes, maximum 30 days
- Length and charset are configurable per secret
- Manual replace and manual rotate are disabled while automatic rotation is active
Opening the Configure Secret interface for a rotating secret shows the schedule editor, where you can pause, resume, or change the interval at any time.
Notes
Each secret has an optional plaintext note. Notes are not encrypted. Use them for context: what the secret is for, who owns rotation, where the upstream credential lives. Editing a note does not create a new version.
Version history
Every replace and every rotation preserves the previous encrypted value. Click the History button () on a secret to see all versions with timestamps.
You can restore any previous version. Restoring creates a new version entry, so rollbacks are themselves versioned.
Version history is kept on every plan, with no per-plan limit on how many versions are retained.
Activity
The History view () also has an Audit tab: a running log of everything that has happened to a secret. Who created it, which machines read it and from where, and every rotation, rename, and note change, newest first. Filter by action, severity, or time to find a specific event.
Access to a secret's activity follows access to the secret itself.
Deleting a secret
Click Delete on a secret to move it to trash:
- Machine access grants are removed immediately
- Rotation schedules are cancelled
- Sync mappings to external platforms (e.g. GitHub Actions) are removed
- The secret remains recoverable from the trash for 30 days
- After 30 days, it is permanently deleted
Machine access
A machine can read a secret only if all six of the following hold at the moment of the request:
- The request includes a valid Ed25519 signature
- The machine is approved
- The machine is enabled
- The vault owner's account is active
- The machine is linked to the secret's project
- The machine has an explicit grant to that specific secret
There is no wildcard access. Adding a machine to a project does not grant it access to any of the project's secrets. Each grant is a separate, explicit row that you add from the project's Machines tab via the Configure button.
If you have configured an access policy bound to this secret, its checks run after the six-requirement gate and before decryption.
What the dashboard shows
The secrets list displays metadata only:
- Secret name and ID
- Secret type indicator
- Rotation indicator if automatic rotation is enabled
- Version number
- Number of machines with access
- Last read time, from the audit log
- Note
- Created and last-updated timestamps
The dashboard never displays decrypted secret values. Secrets are read exclusively by authenticated machines via the SDK or CLI.