Security Overview
A detailed view of how SikkerKey protects encryption keys, secrets, identities, encrypted fallback, access, infrastructure, audit activity, and recovery.
SikkerKey protects secrets through layered encryption, isolated key infrastructure, signed machine identity, vault-scoped authorization, hardened account access, network controls, monitoring, and encrypted recovery systems. This page explains how those protections work together and where responsibility passes to you.
SikkerKey decrypts a secret in memory to serve an authorized read. The service is not zero-knowledge or end-to-end encrypted. Once the plaintext leaves the SikkerKey API, the receiving application becomes responsible for protecting it.
#Encryption at rest
Every secret value is protected by three layers of envelope encryption.
Per-secret data key. Every write receives a fresh 256-bit data-encryption key and a random initialization value. The value is encrypted with AES-256-GCM, which protects confidentiality and detects modification. The secret identifier is authenticated with the ciphertext, so a value encrypted for one secret cannot be substituted for another.
Per-project master key. The data key is itself encrypted under a master key unique to the project. Projects are cryptographically independent: one project key cannot decrypt another project’s data keys.
Isolated root key. Project master keys are encrypted under a root key held on dedicated infrastructure separate from the systems that store and serve secrets. The secret-serving side sends only the wrapped project key to the isolated service and receives that project key for the authorized operation.
The root key remains inside the isolated key infrastructure. It is not transmitted to the systems that store customer data, written to disk, or logged. Project keys are obtained when required and are not cached between requests. Plaintext secret values are decrypted on demand and are never stored in a server-side read cache. When encrypted fallback is enabled, the authorized client stores encrypted local copies as described below.
Passwords and recovery codes are protected with Argon2id. TOTP seeds, webhook signing secrets, synchronization credentials, and other sensitive account or integration data are encrypted with AES-256-GCM under keys separated by purpose.
Customer-managed encryption keys
On eligible plans, you can place your own Google Cloud KMS or OVHcloud KMS key above the vault’s project keys. Activating customer-managed encryption re-encrypts every project master key in the vault so future key operations depend on your provider key.
Continuous enforcement. Every operation that needs a project key calls your configured KMS. SikkerKey does not keep an unwrapped project key between requests or fall back to a local copy.
Control from your provider. Revoking SikkerKey’s provider permission or disabling the key prevents further key operations. Restoring access allows subsequent operations to continue without moving your secret data.
Narrow provider identity. SikkerKey uses a dedicated provider identity for the required encrypt and decrypt calls. Its credential is encrypted under SikkerKey’s isolated root-key boundary and is not used for unrelated access to your cloud account.
Key material stays with your provider. Your KMS key is never exported to SikkerKey. The provider returns only the result of the requested key operation, and you choose the region in which the KMS key resides.
You remain responsible for the availability and retention of a customer-managed key. Permanently deleting or losing it makes the protected vault data unrecoverable. Connecting, activating, disabling, and changing customer-managed encryption are recorded as security events.
#Encryption in transit and browser protection
DNSSEC. SikkerKey signs its DNS records so validating resolvers can verify that the resolved address is authentic.
TLS 1.2 or newer. Cloudflare enforces the minimum protocol at the edge and rejects older TLS connections before they reach SikkerKey.
Strict transport security. Production responses instruct browsers to reuse HTTPS for one year.
Content Security Policy. Every production response receives a restrictive policy with a per-request script nonce. Dashboard scripts must be authorized by the current response, and SikkerKey API content cannot be embedded by another site.
Request-origin checks. State-changing, cookie-authenticated requests must come from an approved frontend origin. Origin and Referer validation works with SameSite cookies to prevent cross-site request forgery.
Browser isolation. Production responses include content-type protection, clickjacking protection, a no-referrer policy, a restrictive Permissions Policy, and cross-origin opener isolation.
Protected cookies. Authentication cookies are HttpOnly, Secure in production, and SameSite=Lax, keeping session state unavailable to browser scripts.
#Machine authentication
Machines authenticate with Ed25519 request signatures rather than reusable bearer tokens. The private key is generated on the machine during bootstrap and never transmitted to SikkerKey. SikkerKey stores only the corresponding public key.
Every signed request covers the HTTP method, request path, timestamp, one-time nonce, and request-body hash. Changing the operation or payload invalidates the signature.
Signatures are verified before a nonce is consumed, preventing an invalid request from burning a legitimate nonce.
Each nonce can be accepted only once.
Requests may be up to five minutes old and no more than one minute ahead, allowing limited clock skew while rejecting stale signatures.
Rate limits track both the source address and the machine identity.
Signed machine routes reject query strings rather than accepting parameters outside the signed request path.
Authentication failures return a restrained response. The specific reason is recorded in the security trail instead of disclosed to the caller.
Checks performed on every secret read
A valid signature proves the machine identity, but it does not grant access by itself. A read continues only when every applicable layer permits it:
the Ed25519 signature, timestamp, body hash, and nonce are valid
the source address satisfies the vault IP allowlist
the machine is approved, enabled, and has not expired
temporary or ephemeral machine restrictions for source network, country, and time are satisfied
the project is active, is not frozen, and belongs to the same vault as the machine
the machine is assigned to the project
the machine has an explicit grant for that secret
the secret’s access policy permits the operation
Project membership does not automatically grant access to every secret in the project. Secret grants remain explicit.
Learn about standard machines, temporary machines, and ephemeral machines.
#Encrypted fallback
The SikkerKey CLI and official SDKs can keep an optional encrypted local copy of successfully retrieved secrets. This allows an authorized workload to continue through a temporary loss of network connectivity or service availability. Encrypted fallback is disabled by default and is activated separately on each client.
Machine-bound encryption. Each cached value is encrypted with AES-256-GCM. Its 256-bit cache key is derived with HKDF-SHA256 from the machine’s Ed25519 private-key seed and vault identifier. The derived key is not stored in the cache.
Context-bound entries. Authenticated metadata binds each entry to its format version, vault, machine, secret identifier, and cache timestamp. Copying an entry to another machine, vault, or secret does not make it usable, and modification is detected during decryption.
Isolated, atomic files. Each secret is stored in its own .skc file beneath the vault’s local identity directory. Entries are written through a temporary file and atomic replacement so readers do not receive a partially written value. The CLI and SDKs use restricted directory and file permissions on platforms that support them.
Server-first automatic fallback. Normal reads contact SikkerKey first. A cached value can be used only after a transport failure, timeout, or a temporary gateway or service-availability response. Authentication failures, denied access, missing or deleted secrets, rate limits, and other authoritative responses are returned to the application and are not replaced with an older value.
Shared format. The CLI and official SDKs use the same versioned cache format, encryption, key derivation, and context binding. A compatible client running as the same machine identity can read entries created by another compatible SikkerKey client.
Using encrypted fallback
Enable and inspect the CLI cache with:
sikkerkey cache enable
sikkerkey cache status
sikkerkey cache clearWhile the cache is enabled, successful get, run, and export reads populate or refresh the relevant entries. If SikkerKey is unreachable, the CLI identifies when a value came from the cache and reports its age. Disabling the feature stops cache reads and writes but keeps existing files until you run sikkerkey cache clear.
Force a cache-only read when you intentionally need to work without contacting SikkerKey:
sikkerkey get sk_... --offline
sikkerkey run --all --offline -- ./app
sikkerkey export --offlineOfficial SDKs enable fallback through their language-specific cache option. They also let you set a maximum cache age and receive a callback when fallback is used. Without a configured maximum age, an SDK cache entry does not expire automatically.
A forced offline read does not contact SikkerKey, so it cannot observe a permission change, machine revocation, rotation, expiry, deletion, or move to Trash that happened after the value was cached. Use offline mode only for an intentional availability window, review the reported cache age, and return to server-verified reads when connectivity is restored.
Protect the local identity directory as you would any system that can access plaintext secrets. A copied cache file is unusable without the matching machine private key, but possession of both places the cached values inside that machine’s security boundary. Clear cached entries when decommissioning the workload, removing its local identity, or when retained values are no longer required.
#AI-agent authentication
AI agents use the same Ed25519 signing, timestamp, nonce, body-integrity, and replay protections as machines, but the two identity systems remain separate. A machine key cannot authenticate as an AI agent, and an AI-agent key cannot authenticate as a machine.
Each agent has its own approval state, management scopes, project access, and audit identity. Its effective permissions are bounded by the current permissions of the person who created it, so narrowing or removing the creator’s access also narrows the agent.
Management agents are plaintext-blind for stored secrets. Metadata operations never return an existing secret value. Tools that create or replace a value accept the new value for encryption and confirm the change without returning it. Runtime secret retrieval remains a machine-authenticated operation.
Open-source clients
Every official SikkerKey SDK and the SikkerKey MCP server is fully open source under the MIT License. You can inspect the authentication, request-signing, secret-reading, and agent-tool implementations in the SikkerKeyOfficial GitHub organization.
Go SDK
Node.js and TypeScript SDK
Python SDK
.NET and C# SDK
Kotlin and Java SDK
PHP SDK
SikkerKey MCP server
The open-source clients let your team review exactly how private keys are loaded, how requests are signed, which data is sent to SikkerKey, and how responses are handled before adopting them in a workload or AI client.
#Dashboard authentication
Passwords, verification, and rate limits
Passwords must be at least 12 characters and include a digit and a non-alphanumeric character. SikkerKey also rejects common passwords, account-related passwords, and passwords with fewer than five distinct characters.
Password verifiers are stored using Argon2id.
Login protection combines source-address and account controls with rate limits, limiting both targeted and distributed attempts.
Email verification codes and similar one-time values are stored as keyed hashes rather than plaintext.
TOTP can provide a second factor. Recovery codes are Argon2id-hashed and single-use, and a challenge is locked after five incorrect TOTP attempts.
Sessions
Access tokens expire after 15 minutes, and each verification confirms that the underlying session remains active.
Changing the password or multi-factor authentication state invalidates existing sessions across devices.
Refresh tokens are single-use and rotate at every refresh. Reuse of an already-rotated token revokes the account’s sessions.
Customer sessions have a 90-day absolute lifetime.
OAuth sign-in is bound to the browser that started the flow through matching state and a protected browser cookie.
The Active Sessions page lets you review devices and revoke sessions you no longer recognize.
Passkeys
SikkerKey supports WebAuthn passkeys as a second factor or, when enabled for the account, as a replacement for the password.
The authenticator keeps the private key; SikkerKey stores only the public key and credential counter.
User verification by the authenticator is required during registration and sign-in.
Every ceremony uses a single-use server-side challenge bound to the browser.
Origins are exact-match, so a passkey registered for the dashboard is accepted only by the dashboard.
A credential-counter regression is rejected and recorded as a critical security event.
Sensitive account actions require a fresh, single-use passkey verification that expires within five minutes.
Passkey-required accounts accept only a passkey or the dedicated recovery flow at sign-in.
Using a passkey recovery code removes all existing passkeys, clears passkey-only settings, revokes other sessions, and requires re-enrollment from a trusted device.
For a passkey-required account, the enrollment recovery codes are the only self-service recovery path. If every authenticator and every recovery code is lost, SikkerKey cannot restore access without creating a bypass around the account’s passkey requirement.
Enterprise SSO
Organizations can require SAML 2.0 sign-in through their identity provider. SikkerKey validates the assertion signature against the configured certificate, the issuer, audience, destination, recipient, validity period, and the original login request. Request state and assertion identifiers are single-use to prevent replay.
Just-in-time accounts are provisioned only for email domains the organization has verified through DNS. When enforcement is enabled, members must use the organization’s identity provider, while the owner retains a controlled break-glass path. Identity-provider configuration is encrypted at rest, and security-sensitive SSO changes require recent account verification.
#Authorization and tenant isolation
Human and workload access are evaluated separately. Vault roles control what an organization member can do across the vault. Access roles determine which applications and projects that member or AI agent can reach and which capabilities are available there. A member without project access can sign in but cannot reach project resources.
Machines require project assignment and individual secret grants. Access policies then narrow how an already-authorized machine may read a secret. These controls do not replace one another; they are evaluated together.
Every customer request remains scoped to its vault. Applications, projects, secrets, machines, AI agents, audit events, and security settings are resolved inside that boundary. Membership in one organization does not provide visibility into another vault.
Project keys reinforce this application boundary cryptographically. Each project’s master key can unwrap only that project’s data keys, and key material is not shared across projects or customers.
Access policies
An access policy can add approved time windows, source IP or CIDR ranges, read-rate limits, a recent read by a selected second machine, a fixed lifetime, a maximum number of reads, or automatic rotation after a configured read count.
When a fixed lifetime expires, the secret moves to Trash and becomes unavailable to normal reads. Maximum-read and rotation controls are evaluated as part of the authorized read path.
Read the Access Policies guide for configuration details.
Temporary and ephemeral guardrails
Short-lived machines can be restricted to specific source networks, countries, and time windows. If SikkerKey cannot place a request inside an allowed country, the geographic check fails closed. These guardrails layer on top of machine approval, project assignment, secret grants, vault allowlists, and access policies.
#Canary secrets and containment
A canary secret looks like an ordinary secret to a machine but is intended to reveal unexpected access. When read, it can freeze the canary’s project and every other project in the same vault that the triggering machine can reach.
The freeze is committed before the response is released. The triggering reader can receive the canary value, but subsequent reads in a frozen project are refused until an authorized user clears the freeze. The canary and project-freeze events are written before the response, so containment does not depend on an operator reacting first.
See Canary secrets for arming, trigger, containment, and recovery guidance.
#Audit trail and alerts
Privileged activity is recorded in an append-only audit log. Database protections enforce that existing events cannot be edited or removed; only the automated retention process removes events after the applicable retention period.
Audit details are sanitized before storage so names and other user-controlled fields cannot inject control characters into an export or downstream log viewer.
Each event identifies the time, action, severity, actor, source IP, and relevant detail. Events cover users, machines, AI agents, and SikkerKey system activity. The durable audit event is written before live dashboard updates and notification delivery.
Retention follows the vault’s plan. High-severity events are retained for twice the standard period, while Critical events remain available as a long-term security record.
Alerts convert selected audit events into email or webhook notifications. You control the minimum severity and delivery channels and can send test deliveries before relying on the configuration.
Use the Audit Log to investigate and export activity, and configure Alerts for events that require attention.
#Network and outbound-delivery controls
Vault IP allowlist
The vault IP allowlist restricts dashboard users, machines, and AI agents to approved IPv4 or IPv6 addresses and CIDR ranges. SikkerKey checks a new configuration against the current connection before activation to reduce accidental lockouts. Changes and denied requests are recorded in the Audit Log.
See IP allowlist for rollout and recovery guidance.
Isolated webhook delivery
Webhook traffic leaves through a dedicated relay separated from the infrastructure that stores and serves secrets. Before delivery, the relay rejects reserved and internal destination ranges and pins the connection to the validated address, preventing a redirect or DNS change from sending the request to a protected internal service.
Webhook deliveries originate from the stable address 49.13.140.25. Allowlist this address when your endpoint restricts inbound traffic.
Service hardening
Rate limits cover sign-in, registration, password reset, verification, machine authentication, bootstrap, enrollment, webhook delivery, and the general API.
Three failed machine-authentication attempts within five minutes lock both the source address and the machine for 30 minutes.
Request-size limits are enforced before application handlers process the request. Requests that do not declare their size are rejected.
Unexpected failures return a generic error while internal reporting avoids recording the exception message or request contents.
SikkerKey does not accept application traffic until security-critical services, including the isolated key connection, are ready.
Private tunnels
A tunnel connects one host inside a customer network to SikkerKey without that network accepting inbound connections. The connector always dials out, so reaching a database or internal service over a tunnel requires no inbound firewall rule and no exposed port.
Both directions are authenticated with separate Ed25519 key pairs, and each side generates the key it signs with. The connector's private key is created during installation and never leaves the host; SikkerKey holds a distinct key pair for each tunnel, and the connector pins its public half at installation.
Only public keys are transmitted. Each request to open a connection is signed over the target, a timestamp, and a nonce. The connector verifies that signature against the pinned key before it resolves an address or opens a socket, and rejects a timestamp outside a five minute window, a nonce it has already seen, and any target not declared on that tunnel.
A tunnel also carries no traffic until the customer approves it in the dashboard. The declared target list is the boundary on reach. A tunnel can only open connections to the endpoints the customer has named on it, and removing a target ends its reachability immediately. The service that holds tunnel connections stores no keys and no customer state.
Signing happens on the infrastructure that holds the key material, and the tunnel service forwards a finished request it cannot produce itself.
#How SikkerKey protects its own application secrets
SikkerKey stores its operational credentials in a dedicated vault under the same envelope-encryption model used for customer secrets, rather than placing them in environment variables or configuration files.
SikkerKey services authenticate to that vault through a dedicated Ed25519 machine identity. Reads are subject to the normal machine authorization path and are recorded in the audit trail. If a service cannot retrieve the credentials it needs through this protected path, it does not begin serving application traffic.
Possession of the production database alone therefore exposes ciphertext for both customer secrets and SikkerKey’s own operational credentials, without the root key required to unwrap project keys.
#Encrypted backups
A full database backup runs every day at 03:00 UTC.
A compressed database dump is created.
The dump is encrypted with AES-256-GCM under a dedicated backup key, separate from secret data keys and the root key.
A SHA-256 checksum is computed over the encrypted bytes.
The encrypted backup and checksum are sent over HTTPS to a separate backup service.
Each upload is signed, timestamped, and replay-protected. The receiving service verifies the signature, body, nonce, and checksum before accepting the file.
Every push records its trigger, result, size, checksum, and timestamp.
The backup service stores encrypted blobs without the backup key. The key is held as a SikkerKey application secret and can be obtained only through the isolated key path used for other protected operational credentials.
#Hosting and data residency
SikkerKey production runs on Hetzner bare-metal infrastructure in Germany, without shared virtual machines or US-hosted production infrastructure.
Inbound production traffic reaches SikkerKey through a Cloudflare Zero Trust tunnel rather than exposing the origin directly.
Production data at rest remains in the EU. The primary database is in Germany and encrypted backups are stored in Denmark.
Cloudflare terminates TLS at its global edge and proxies the protected connection to the German origin. The edge location may be outside the EU, depending on the connecting user.
Backup storage runs on a physical server owned and operated by SikkerKey in Denmark, separate from the production hosting provider. The backup key is not stored on that hardware.
SikkerKey is based in Denmark. Current infrastructure, payment, and delivery providers are listed in the public sub-processor register.
IP geolocation uses a locally hosted dataset. Customer addresses are not sent to a third-party geolocation API.
See the current sub-processor register for the providers involved, their purpose, processed data, location, and transfer mechanism.
#Data and key boundaries
Stored or processed by SikkerKey | Kept outside SikkerKey |
|---|---|
Encrypted secret ciphertext and wrapped data keys | Machine private keys and optional encrypted fallback cache entries, which are generated and retained by your machines |
Secret plaintext while fulfilling an authorized request; SikkerKey does not persist it or keep a server-side read cache | Passkey private keys, which remain in the user’s authenticator |
Machine public keys | Your SAML identity provider’s private signing key |
Passkey public keys and credential counters | Your customer-managed KMS key material |
Encrypted SAML provider configuration | Payment-card details, which are handled by Stripe |
A dedicated encrypted provider credential for customer-managed key operations | Plaintext passwords and recovery codes |
Argon2id password and recovery-code verifiers | The root key on systems that store and serve customer data |
Account data, audit events, and rate-limit state | SikkerKey application secrets in environment variables or configuration files |
Encrypted webhook signing secrets, TOTP seeds, and synchronization credentials | Backup decryption keys on the backup server |
#Employee data access
SikkerKey’s employee tooling does not provide a route to read, create, update, rotate, roll back, rename, or individually delete a customer secret. It also does not provide a route to approve, revoke, rename, bootstrap, or change grants for a customer machine.
What employees can access
Customer account, subscription, support-ticket, SLA, and suspension information needed to operate the service.
A customer’s Audit Log when investigating a support request. Audit events do not contain secret values, passwords, recovery codes, private keys, or session tokens.
Resource names and aggregate counts used for account support, without secret values.
Account-level deletion. Deleting an account triggers the customer-data lifecycle for the entire account rather than providing an employee with individual secret or machine controls.
Protected customer operations
No employee endpoint decrypts a customer secret or retrieves its project key.
Employees cannot use a support-write path to change customer secret values.
Machine lifecycle and machine-to-secret grants remain under customer control.
Employee impersonation is restricted to SikkerKey-operated internal vaults.
Direct database access yields encrypted values and wrapped project keys. The separate root-key boundary is required to decrypt them, and employee credentials and support tools do not provide that key path.
#Secret lifecycle and Trash
Deleting a supported resource moves it to Trash for a recovery period. Trashed resources are unavailable to normal operations, can be restored while retained, and can be permanently deleted by an authorized user.
TTL secrets use the same lifecycle. When the lifetime expires, SikkerKey moves the secret to Trash, records the event, and applies the normal restoration and permanent-deletion controls.
See Trash and TTL secrets for lifecycle behavior.
#Vulnerability disclosure
SikkerKey maintains a Vulnerability Disclosure Program for security researchers and customers who identify a potential weakness. The program explains the authorized testing scope, reporting process, safe-harbor terms, and the information that helps SikkerKey investigate a report.
Report a suspected vulnerability through the SikkerKey Vulnerability Disclosure Program. Avoid including customer secret values, private keys, passwords, session tokens, or other sensitive production data in the initial report.
#Where responsibility transfers
SikkerKey’s controls protect a secret until it is returned to an authorized client. Responsibility transfers at three important points:
The API response enters your process. Your CLI, SDK, CI runner, server, or other authenticated client now holds the plaintext. SikkerKey cannot control whether that process logs, caches, forwards, or securely discards it.
You grant access to an organization member. The member can perform the actions granted by their vault role and access role, including attaching workloads when permitted.
A managed-secret rotation completes. The new credential is active in the target system. Protection of the target database, provider, or service remains part of that system’s security boundary.
Your security responsibilities
Protect machine private keys and remove them when a workload is decommissioned.
Protect dashboard passwords, second factors, passkey authenticators, and recovery codes.
Review who belongs to the vault and grant only the roles and projects each person needs.
Maintain your identity-provider configuration and verified SSO domains.
Keep a customer-managed KMS key and SikkerKey’s permission to use it available for as long as the vault depends on it.
Keep the vault IP allowlist aligned with your current users, machines, agents, and automation.
Review Alerts and the Audit Log, investigate unexpected activity, and freeze affected projects when needed.
Keep plaintext secrets out of logs and error reports after your application receives them.
Rotate credentials after suspected exposure.
Use separate machine identities for separate workloads, explicit secret grants, short-lived identities for temporary infrastructure, access policies for sensitive credentials, and canary secrets where access should never occur during normal operation.