Privacy Policy

Effective May 1, 2026
Section 01

Data Controller

The data controller responsible for the processing of your Personal Data is:

SikkerKey
Denmark
Email: [email protected]

“Personal Data” has the meaning given in Regulation (EU) 2016/679 (General Data Protection Regulation). Where this Policy refers to “processing,” it encompasses any operation performed on Personal Data, including collection, storage, use, disclosure, and deletion.

Section 02

Data We Collect

We collect and process the following categories of Personal Data:

  • Account data — Username, email address, hashed password (Argon2id, 64 MB memory, 3 iterations), account status, and email verification status. Provided by you at registration.
  • Network data — IP addresses used to access the Service, including your registration IP, login IPs, session IPs, and machine last-seen IPs. Collected automatically.
  • Session and device data — User-Agent strings, session identifiers, and session creation/usage timestamps. Collected automatically.
  • Geolocation data — Country and city derived from your IP address via locally-hosted MaxMind GeoIP databases. No IP addresses are transmitted to MaxMind for this purpose. Derived automatically per session and login event.
  • Authentication event data — Login attempts (successful and failed) with IP address, geolocation, timestamp, and failure reason. Failed login attempt counters and account lockout timestamps. Collected automatically.
  • Machine metadata — Machine name, Ed25519 public key, registration IP, last-seen IP and timestamp, approval status, and machine name change history. Provided by machine operators during bootstrap.
  • Audit log data — Every action performed in your vault is logged with the acting user or machine ID, action type, severity level, source IP address, contextual detail text, and millisecond timestamp. Generated automatically.
  • OAuth identity data: If you sign in or sign up with a GitHub or Google account, we receive and store the provider's stable user identifier, email address, email-verified flag, display name, and avatar URL. Received from the provider during the OAuth flow.
  • Two-factor authentication data: Encrypted TOTP secret (AES-256-GCM at rest), Argon2id-hashed recovery codes (single-use). Generated when you enable 2FA.
  • Passkey (WebAuthn) data: For each passkey you register, we store the credential public key, a signature counter, the authenticator’s AAGUID and transport hints, a user-chosen friendly name, and registration plus last-used timestamps. We also store Argon2id-hashed recovery codes (single-use) generated at first passkey enrollment, used to regain access if you lose your authenticator. The passkey’s private key never leaves your authenticator and is never transmitted to or stored by SikkerKey. Generated when you register a passkey from the dashboard.
  • Billing data — Stripe customer ID, Stripe subscription ID, billing interval, subscription status, and current billing period dates. Payment card details, invoices, and billing addresses are managed exclusively by Stripe and are not stored on SikkerKey systems.
  • Team and collaboration data — Team invitations (invitee email, status, timestamps), team membership records, and per-project permission grants. Provided by vault owners.
  • Support ticket data — Ticket title, messages, priority, status, satisfaction ratings, and file attachments (encrypted at rest with AES-256-GCM). Provided by you when submitting support requests.
  • Rate limiting data — IP addresses, lockout records, violation counts, and associated endpoint paths for security-critical rate limit escalations. Generated automatically.
  • Suspension data — Suspension category, reason detail, duration, and administering employee. Generated during account enforcement actions.
  • Enrollment token data — Token hashes (SHA-256), policy configuration (selected projects and secrets, token lifetime, machine lifetime, maximum uses, optional source CIDR, optional hostname regex, optional machine-name template), revocation state, and revocation reason. Generated when you create enrollment tokens for ephemeral machines.
  • Webhook data — Endpoint URLs, HMAC secret hashes (SHA-256), subscribed action filters, delivery health status, consecutive failure counts, and last delivery and error messages. Provided by you when configuring webhook endpoints for real-time alerts.
  • IP allowlist data — CIDR ranges, entry labels, and creation timestamps. Provided by you when configuring network-level access restrictions on your vault.
  • CI/CD integration data — For GitHub: GitHub App installation identifiers and repository metadata (owner, name, workflow presence). For GitLab and Bitbucket: encrypted OAuth access and refresh tokens, workspace or project identifiers, repository names, and pipeline configuration status. Received from the respective platforms during OAuth flows or app installation. Distinct from the GitHub social-login OAuth identity data described above.
  • Secret sync configuration — Target platform, repository or project identifiers, platform-specific metadata, per-mapping sync status, last synced version, last sync timestamp, consecutive failure counts, and error messages. Generated when you configure secrets to push into CI/CD platform variable storage.
  • Managed secret configuration — Encrypted database connection details (host, port, database name, admin username and password, all AES-256-GCM at rest), managed role name, assigned agent machine, heartbeat timestamps, heartbeat error messages, and rotation status. Generated when you enable automatic database credential management for a secret.
  • Dynamic lease data — Encrypted revocation material, lease status (active, revoked, expired), expiration timestamps, revocation attempt counts, and revocation error messages. Generated when machines issue temporary credentials through dynamic secret providers.
  • Temporary secret data — Share-link tokens, passphrase hashes (Argon2id), status (pending, viewed, destroyed, expired), expiration timestamps, and creator identifiers. Generated when you create one-time self-destructing secrets for human-to-human credential handoff.
  • Rotation configuration — Rotation interval, generated-value length and character set, which fields rotate (for structured secrets), last rotation timestamp, and next scheduled rotation. Configured when you enable automatic secret rotation on a secret.
  • Website audience measurement — Anonymous first-party analytics on our marketing website. Includes a per-tab session identifier stored in browser sessionStorage, a short visitor hash, landing page path, referrer domain, traffic source, country code (derived from IP via locally-hosted MaxMind), device type, and page-level events (page views, scroll depth milestones, clicks on tagged elements, page-exit duration). No advertising identifiers, third-party analytics services, or cross-site tracking are used. Classified as CNIL-exempt audience measurement; no consent prompt is required under Article 5(3) of the ePrivacy Directive.

We do not collect or process special categories of Personal Data (e.g., racial or ethnic origin, political opinions, health data, biometric data) as defined under Article 9 of the GDPR.

Encrypted secrets are not Personal Data under our control. Your vault secrets are encrypted with three layers of AES-256-GCM encryption. We cannot access, read, or process the plaintext content of your secrets from a database backup alone. We do not know what data you store.

Section 04

How We Use Your Data

We use the data we collect for the following purposes:

  • To create, authenticate, and manage your account and sessions.
  • To derive encryption keys during authenticated requests and immediately destroy them after.
  • To verify machine Ed25519 signatures and enforce replay protection.
  • To enforce access control: project membership, per-secret machine grants, and team permissions.
  • To maintain a severity-tagged audit trail of all vault operations.
  • To dispatch real-time security alerts via email and SSE when configured by you.
  • To enforce rate limits, detect abuse, and prevent unauthorized access.
  • To process subscription billing through Stripe.
  • To provide customer support and resolve support tickets.
  • To send transactional emails: verification codes, password reset links, login notifications, team invitations, and security alerts.
  • To comply with applicable legal obligations.

We do not use your Personal Data for profiling, automated individual decision-making with legal effects, advertising, or sale to third parties.

Section 05

Data Sharing & Disclosure

We do not sell, rent, or trade your Personal Data. We may share data in the following limited circumstances:

  • Infrastructure providers — We use third-party hosting and infrastructure services to operate the Service. These providers process data on our behalf under data processing agreements compliant with Article 28 GDPR. See our sub-processor list.
  • Payment processing — Stripe processes payment data on our behalf. Stripe’s privacy policy governs the handling of payment card data, billing addresses, and invoice information. SikkerKey does not store or have access to your payment card details.
  • Geolocation — IP addresses are processed against locally-hosted MaxMind GeoIP databases on our infrastructure. No Personal Data is transmitted to MaxMind.
  • Law enforcement — We may disclose data when required by law, court order, or governmental authority, or where necessary to protect the rights, safety, or property of SikkerKey, its users, or the public. Vault secrets are protected by three layers of encryption, and the decryption root is not stored on disk. We cannot provide decrypted secret values from a database backup even under legal compulsion.

We do not share your registration data, account details, audit logs, or any other Personal Data with other users of the Service. Team members can see project and machine metadata within vaults they have been invited to, as configured by the vault owner.

Section 06

International Data Transfers

SikkerKey is based in Denmark and processes data within the European Economic Area (EEA) using Hetzner infrastructure located in the EU. Where data is transferred outside the EEA (e.g., Cloudflare edge nodes, Stripe payment processing), we ensure appropriate safeguards are in place in accordance with Chapter V of the GDPR, including:

  • European Commission adequacy decisions (Article 45 GDPR).
  • Standard Contractual Clauses approved by the European Commission (Article 46(2)(c) GDPR).
  • The EU-U.S. Data Privacy Framework, where applicable.

You may request information about the specific safeguards applied to international transfers by contacting us at the address provided in the Contact section.

Section 07

Data Retention

We retain Personal Data only for as long as necessary to fulfill the purposes described in this Policy, unless a longer retention period is required by law.

  • Account data — Retained for the lifetime of the account. Deleted within 30 days of account deletion.
  • Audit logs — Retained for a period gated by your subscription plan, pruned automatically on an hourly schedule. Higher-severity entries are kept longer: high-severity events for twice that period, and critical security events (authentication failures, two-factor changes, account revocation, IP allowlist changes, project deletion, vault destruction) for the life of the vault.
  • Login event history — Retained for the lifetime of the account.
  • Sessions — Expire after 24 hours, or 30 days with “remember me.” Expired sessions are cleaned up automatically.
  • Deleted secrets (trash) — Soft-deleted secrets remain recoverable for 30 days, after which they are permanently and irreversibly deleted.
  • Verification codes — Email verification codes expire after 10 minutes. Password reset tokens expire after 1 hour. Both are single-use.
  • Replay protection nonces — Expired nonces (older than 6 minutes) are pruned every 60 seconds.
  • Rate limit lockouts — Expire per their configured duration (ranging from 15 minutes to 24 hours depending on the policy).
  • Support tickets — Retained for the lifetime of the account. Tickets auto-close after 7 days of inactivity.
  • Temporary (share-link) secrets — Self-destruct on first view, on wrong passphrase, or at their configured expiry (1 minute to 24 hours). Never retained beyond their TTL.
  • Dynamic leases — Retained until the lease’s TTL expires or the lease is revoked. Historical lease records are pruned according to the audit-log retention of your plan.
  • Website audience measurement — Visitor sessions, events, and aggregates are retained for 13 months, after which they are deleted automatically by a daily cleanup job. This retention applies to unauthenticated website visitors and is not tied to any account.

Upon account deletion, all personal data, encrypted secrets, projects, machine registrations, team relationships, and audit history are permanently deleted within 30 days, subject to legal obligations requiring continued retention. That window matches our encrypted backup retention, so a destroyed vault is erased from both production and backups within the same period. An account suspended for abuse may be retained beyond this on a legitimate-interest basis for security and abuse prevention.

Section 08

Cookies & Storage

The Service uses strictly necessary cookies for authentication and session management, and first-party browser sessionStorage for anonymous website audience measurement. We do not use advertising cookies, third-party tracking pixels, or third-party analytics services.

  • access_token — Short-lived JWT that authenticates your requests to the Service. Duration: 15 minutes. HttpOnly, Secure, SameSite=Lax.
  • refresh_token — Maintains your session and issues new access tokens without re-authentication. Duration: 24 hours, or 30 days with “remember me.” Path-scoped to the authentication endpoints. HttpOnly, Secure, SameSite=Lax.
  • has_session — Marks that an active session exists. HttpOnly, Secure, SameSite=Lax.
  • sk_2fa_challenge — Set during login when your account has two-factor authentication enabled. Carries the short-lived JWT that authorises your TOTP submission so the dashboard never has access to it. Duration: 5 minutes. Path-scoped to the 2FA verification endpoint. HttpOnly, Secure, SameSite=Lax.
  • sk_oauth_state — Set when you initiate a GitHub or Google login. Binds the OAuth callback to the originating browser to defeat OAuth login-CSRF and session-fixation attacks. Duration: 10 minutes. Path-scoped to the OAuth endpoints. HttpOnly, Secure, SameSite=Lax.
  • sk_oauth_link_state: Set when you link an OAuth provider to an existing account from the dashboard. Same browser-binding role as sk_oauth_state, scoped to the link callback so it cannot be cross-replayed against the login flow. Duration: 10 minutes. Path-scoped to the dashboard OAuth-link endpoints. HttpOnly, Secure, SameSite=Lax.
  • sk_webauthn_register, sk_webauthn_register_signup, sk_webauthn_login, sk_webauthn_2fa, sk_webauthn_step_up_req: Set during a passkey ceremony (registration, signup, sign-in, second-factor verification, or step-up). Each carries an opaque random handle to a server-side challenge record. The challenge bytes themselves never leave our server. Duration: 5 minutes. Path-scoped to the matching ceremony endpoint. HttpOnly, Secure, SameSite=Lax.
  • sk_step_up: Set after a successful passkey step-up verification. Authorises one immediately-following destructive action (such as removing a passkey, removing the password, linking or unlinking an OAuth provider, disabling 2FA, disabling the IP allowlist, or destroying the vault). Single-use, cleared the moment the destructive action completes. Duration: 5 minutes. Path-scoped to the dashboard surface. HttpOnly, Secure, SameSite=Lax.
  • _sk_sid (browser sessionStorage, not a cookie) — Per-tab session identifier used to correlate anonymous audience-measurement events within a single browsing session on the marketing website. Cleared automatically when the browser tab closes. Not transmitted in any request; used only as the key under which events are batched before delivery.

Every cookie listed above is set with the HttpOnly flag, meaning client-side JavaScript cannot read it. The Secure flag ensures cookies are only transmitted over encrypted HTTPS connections. Refresh tokens are SHA-256 hashed before server-side storage; plaintext tokens are never persisted. The 2FA-challenge and OAuth-state cookies are short-lived and consumed within the auth flow that sets them.

Strictly necessary cookies do not require consent under Article 5(3) of the ePrivacy Directive (2002/58/EC), as they are essential for the functioning of the Service. The sessionStorage-based audience measurement is similarly exempt as first-party aggregate analytics (CNIL exemption criteria).

Section 09

Your Rights Under GDPR

As a data subject under the GDPR, you have the following rights:

  • Right of access (Article 15) — You may request a copy of the Personal Data we hold about you.
  • Right to rectification (Article 16) — You may request correction of inaccurate or incomplete Personal Data.
  • Right to erasure (Article 17) — You may request deletion of your Personal Data, subject to legal retention obligations and the exceptions set out in Article 17(3).
  • Right to restriction (Article 18) — You may request that we restrict processing of your data while a dispute or verification is pending.
  • Right to data portability (Article 20) — You may request a machine-readable export of the Personal Data you provided to us.
  • Right to object (Article 21) — You may object to processing based on legitimate interest. We will cease processing unless we demonstrate compelling legitimate grounds.

To exercise any of these rights, contact us at [email protected]. We will respond within 30 days, as required by Article 12(3) GDPR. We may request verification of your identity before processing your request.

You also have the right to lodge a complaint with a supervisory authority. The relevant authority for SikkerKey is the Danish Data Protection Agency (Datatilsynet): datatilsynet.dk.

Section 10

Security Measures

We implement appropriate technical and organizational measures to protect Personal Data against unauthorized access, alteration, disclosure, or destruction, in accordance with Article 32 of the GDPR. These measures include:

  • Secrets encrypted at rest using three-layer AES-256-GCM envelope encryption with per-secret data keys, per-project master keys, and a decryption root that exists only in server memory.
  • Passwords hashed using Argon2id (64 MB memory, 3 iterations). Plaintext passwords are never stored or logged.
  • TOTP secrets encrypted at rest with AES-256-GCM using a server-side data encryption key.
  • Machine authentication via Ed25519 signatures with replay protection (timestamp window + nonce tracking).
  • All data in transit encrypted using TLS.
  • Rate limiting with escalating lockouts on authentication endpoints.
  • Security headers enforced: HSTS, X-Frame-Options DENY, X-Content-Type-Options nosniff, CSP, Referrer-Policy no-referrer.
  • Geolocation performed against locally-hosted databases. No user IP addresses transmitted to external geolocation services.
  • Support ticket attachments validated (magic byte MIME detection, dimension limits), sanitized (PDF JavaScript/action removal), and encrypted at rest.
  • Access to production systems restricted to authorized personnel.

No system is completely secure. In the event of a data breach affecting your Personal Data, we will notify you and the relevant supervisory authority in accordance with Articles 33 and 34 of the GDPR.

Section 11

Children's Privacy

The Service is designed for software engineers, DevOps teams, and organizations managing application secrets, and is not directed at children. In accordance with Article 8 of the GDPR and the Danish implementation setting the age of digital consent at 16, we do not knowingly collect Personal Data from individuals under the age of 16.

If we become aware that we have collected Personal Data from a child under 16 without valid parental consent, we will take steps to delete that data promptly. If you believe a child under 16 has provided data to us, contact us at [email protected].

Section 12

Changes to This Policy

We may update this Privacy Policy to reflect changes in our practices, the Service, or applicable law. Material changes will be communicated via email to the address associated with your account or through a prominent notification in the dashboard at least 30 days before they take effect.

The effective date at the top of this Policy indicates when it was last updated. Continued use of the Service after changes take effect constitutes acceptance of the revised Policy.

Section 13

Contact

For privacy inquiries or to exercise your data protection rights, contact:

SikkerKey
Email: [email protected]
Web: sikkerkey.com