A simple secrets manager should absorb complexity
A simple secrets manager is not one with no security model. That usually means the hard parts were pushed into a token, an environment variable, a wiki page, or a manual checklist.
SikkerKey is built around a different idea: absorb the complexity inside straightforward methods and intuitive UI. A developer creates a project, stores a secret, bootstraps the machine that needs it, grants that machine access to the specific secret, and reads it at runtime through the CLI or a read-only SDK.
The model stays understandable because the core objects match how teams already think about deployment:
- projects hold related secrets
- machines are the things that read secrets
- grants connect one machine to one secret
- every read is signed, checked, decrypted, and audited
That is the product shape behind SikkerKey's simplicity. It avoids the two patterns that make many secrets tools feel heavy: long-lived bearer tokens copied between systems, and broad role policies that require a second system of documentation to understand who can read what.
One command bootstraps a real machine identity
The machine bootstrap flow is where SikkerKey hides a lot of necessary security work without hiding the security model.
In the dashboard, the Bootstrap modal creates a one-time token that expires after 10 minutes and shows the right command for Linux, macOS, or Windows. The operator copies the command and runs it on the target machine.
Behind that simple UI, the script does the work a security-conscious team would otherwise have to design for itself:
- validates the bootstrap token format
- checks local prerequisites like OpenSSL and curl
- generates an Ed25519 keypair locally
- sends only the public key to SikkerKey
- registers the machine against the vault
- writes a vault-scoped identity file under
.sikkerkey - stores the private key with restrictive filesystem permissions
- points runtime reads at SikkerKey's machine-service retrieval plane
The private key never leaves the machine. The dashboard then shows the machine in pending state so an operator can approve, deny, rename, disable, or revoke it.
That is the difference between simple and simplistic. The user sees one copyable command and a clear approval step. SikkerKey still gives the machine a real asymmetric identity rather than asking the team to paste another shared API key into production.
The setup model is project, machine, grant
SikkerKey's dashboard is organized around projects first. A project is the workspace for a production app, staging app, service, customer environment, or other boundary that makes sense to the team. Secrets live inside that project.
Machines are managed separately from secrets. A machine can be approved, denied, renamed, disabled, revoked, added to a project, or removed from a project. Project membership is still not enough to read a secret. SikkerKey requires a specific secret grant before a machine can fetch a value.
The UI makes that visible. In a project's machine view, each machine shows its secret count. Configuring access opens a two-column Available and Granted view where operators can move individual secrets in or out. There is no wildcard access hiding in the background.
For teams trying to adopt secrets management for the first time, this matters. You do not need to design an access-control taxonomy before storing the first API key. Start with a project, add a machine, grant the secrets it needs, and tighten from there.
Machine authentication replaces copied API keys
The most important simplification in SikkerKey is that applications do not authenticate with a shared API key.
When a machine reads a secret, the request is signed with its Ed25519 private key. The request includes the machine id, timestamp, nonce, body hash, and signature. The server verifies the signature against the machine's public key and then checks approval state, project membership, explicit secret grants, project freeze state, and any access policy before decrypting the value.
For developers, this removes an awkward question: where do we store the credential that lets us fetch the rest of the credentials?
With SikkerKey, the machine identity is local and asymmetric. There is no bearer token to paste into CI settings, bake into an image, or rotate across ten platforms. If a machine should no longer read secrets, disable or revoke that machine. If it only needs a subset of secrets, adjust that machine's grants.
This is why SikkerKey can be simple without being loose. The secure object is the machine, not a copied string.
Six read-only SDKs use the machine identity automatically
SikkerKey's SDKs are deliberately read-only. They are not admin clients for creating projects, changing grants, or editing secrets from application code. Their job is narrower and safer: let an approved machine read the secrets it has already been granted.
The official SDKs cover six languages:
- Node.js
- Python
- Go
- .NET
- Kotlin/JVM
- PHP
Across those languages, the shape is intentionally consistent. A client loads or auto-detects the machine identity, signs requests with the machine's private key, and exposes small methods for runtime reads:
const sk = SikkerKey.create('vault_abc123')
const apiKey = await sk.getSecret('sk_stripe_key')
const password = await sk.getField('sk_db_prod', 'password')
const env = await sk.export('proj_production')
The same idea appears in each language with native naming: getSecret, getFields, getField, listSecrets, listSecretsByProject, and export or their idiomatic equivalents.
That is what makes the SDKs simple in practice. Application code does not need to know how bootstrap tokens work, where policies are stored, how grants are represented, or how Ed25519 signatures are assembled. It references the local machine identity and asks for a secret. SikkerKey decides whether that machine is allowed to receive it.
Serverless can enroll in memory
Long-lived hosts can use the identity written by the bootstrap script. Serverless, short-lived, and read-only filesystem environments often cannot.
For that case, the SDKs support in-memory bootstrap from an enrollment token. The app supplies a vault id and enrollment token, the SDK generates an Ed25519 keypair in memory, enrolls an ephemeral machine, and returns a normal read client. Nothing is written to disk. When the process exits, the private key is gone.
The enrollment token still controls the important boundaries: projects, secret grants, token lifetime, machine lifetime, max uses, and optional restrictions like source CIDR, hostname pattern, and name pattern. The token itself cannot read secrets. It can only create scoped machines according to the policy configured in the dashboard.
That lets teams use the same model across laptops, servers, CI runners, containers, and serverless functions: machines read secrets; grants decide which secrets; the SDK signs requests automatically.
The CLI stays close to the workflow
A secrets manager becomes complex when using it requires a custom integration project. SikkerKey's CLI is intentionally small and operational:
sikkerkey list secrets
sikkerkey get <secret_id>
sikkerkey get <secret_id> password
sikkerkey run --all --project production -- node app.js
sikkerkey export --project production --format json
The CLI reflects live grants. If a machine can read three secrets in a project, those are the secrets it can list, fetch, export, or inject. If access is revoked in the dashboard, the CLI does not keep a local policy cache that continues to say otherwise.
For local development, sikkerkey run is the practical bridge. It injects selected secrets, or all granted secrets from a project, into a child process as environment variables. Structured secrets expand into field-level variables, so a JSON-shaped database credential can become separate username and password variables for frameworks that expect them.
For rotation-sensitive services, --watch can restart the child process when watched secrets change. That keeps the developer experience familiar while moving the source of truth out of local plaintext files.
Enrollment tokens make ephemeral infrastructure manageable
Simple setup for one laptop is useful. Simple setup for CI runners, autoscaling groups, and short-lived containers is harder.
SikkerKey handles that with enrollment tokens. An enrollment token can define:
- which projects enrolled machines join
- which secrets they receive grants for
- how long the token can be redeemed
- how long each enrolled machine lives
- how many times the token can be used
- optional source CIDR, hostname, and naming restrictions
The important part is that these choices happen once, when the token is created. Machines enrolled through that token receive the intended project memberships and secret grants automatically. Operators do not need to approve every short-lived runner by hand or run a follow-up script to attach access.
The dashboard still keeps the model visible. An enrollment token shows its granted projects, granted secrets, redemption count, and enrolled machines. If the token should stop creating new machines, revoke it. Existing machines keep their own identities and lifetimes, so the operational impact is clear.
The read path has guardrails without extra ceremony
When a machine reads a secret, SikkerKey does more than check that the secret exists.
The runtime read path verifies the signed request, checks the machine state, checks project membership, checks the explicit machine-to-secret grant, blocks frozen projects, evaluates any bound access policy, decrypts the value, records the audit event, updates read counters, and handles canary or rotation side effects.
Most of that is invisible when everything is working. That is the point. Teams get rate limits, TTL-style read limits, rotate-after-read triggers, canary tripwires, project freezes, and audit events without forcing every app team to implement that logic in code.
SikkerKey's access policies are layered on top of the basic grant model. A secret can be unbound and use the base gate only, or bound to a policy with constraints like time windows, IP allowlists, rate caps, co-sign checks, expiration, max reads, or rotate-after-N reads. The app still reads the secret the same way. The policy changes on the server.
The dashboard makes advanced flows first-class
A simple secrets manager should not mean only static key-value storage. It should make common secret operations understandable:
- create a plain secret
- create a structured secret with named fields
- generate and rotate values automatically
- create managed database credentials
- create one-shot temporary secrets
- plant canary secrets that freeze a project when read
- inspect read activity and audit logs
- approve, disable, or revoke machines
SikkerKey exposes those as normal dashboard workflows instead of external recipes. Creating a canary secret includes the operational triggers directly in the form. Creating an enrollment token includes project and secret access in the same flow as lifetime and redemption limits. Configuring machine access uses a clear Available and Granted interface that is easy to audit by eye.
That is where simplicity shows up for real teams. The product does not ask one person to understand security deeply and then translate it into scattered scripts for everyone else. The intended controls are in the UI, backed by the same machine-service enforcement path the CLI and SDKs use.
What simple should mean for secrets management
A simple secrets manager should give teams a path that works on day one and still holds up when the system grows. Simple does not mean compromise on security, but a secure system should not push complexity onto the user, it should absorb it and make the secure path the default path.
SikkerKey's path is intentionally direct:
- Create a project.
- Add secrets to it.
- Bootstrap or enroll the machines that need them.
- Grant each machine only the secrets it should read.
- Read secrets through the CLI or one of the six read-only SDKs.
- Use audit logs, policies, canaries, and rotation where the risk calls for them.
That is the simplicity SikkerKey is aiming for: fewer copied credentials, fewer hidden policy layers, fewer platform-specific secret stores, and fewer places where a developer has to invent a secure workflow alone.
If you are looking for a simple secrets manager, do not look only for the fewest buttons. Look for the shortest path from storing a secret to letting the right machine read it safely. That is where SikkerKey is designed to be simple.