Exactly what happens to your code and credentials

Riftmap asks for a read-only access token to scan your organisation. This page explains precisely what we do with that access — no ambiguity, no hand-waving.

three guarantees
  • Source code is never stored. Only dependency metadata (names, versions, line numbers) persists. Code is cloned to a temporary directory, parsed, and deleted.
  • Tokens are encrypted at rest. AES-128-CBC via Fernet symmetric encryption. The encryption key lives in an environment variable, physically separate from the database.
  • Zero per-repo configuration. Read-only access only. No agents installed, no webhooks registered, no code changes in your repositories. Disconnect anytime.

What happens during a scan

Every scan follows this exact sequence. Each step is auditable in the codebase.

  1. 01

    Enumerate

    Platform API lists repository names and metadata. No code is accessed at this stage.

  2. 02

    Clone

    Shallow clone (depth=1, latest commit only, no history) to a temporary worker directory. No commit history is downloaded.

  3. 03

    Restrict

    Clone directory set to 0700 (owner-only) before git writes any content. No other OS process can read the files.

  4. 04

    Parse

    Only dependency manifest files are read (go.mod, package.json, Dockerfile, Terraform, CI configs, etc.) to extract dependency references.

  5. 05

    Store

    Only the dependency graph is written to the database: names, version constraints, line numbers. No source code.

  6. 06

    Delete

    Clone directory deleted via shutil.rmtree() in a try/finally block — runs even on parser exception or timeout. A Celery Beat task sweeps for orphaned clones every 15 minutes.

Hung clones are killed after 120 seconds. The cleanup is guaranteed by a try/finally block — it runs whether parsing succeeded, failed, or timed out.

What we store vs. what we don't

What persists in the database
  • Repository names and platform IDs
  • Dependency names and version constraints
  • Source file paths and line numbers where dependencies are declared
  • Scan timestamps, status, and per-repo lifecycle events
  • Artifact names (e.g. Docker image tags, npm package names)
What is never stored
  • Source code content of any kind
  • File contents beyond manifest metadata
  • Commit history (shallow clone — no history downloaded)
  • Secrets, environment variables, or .env files
  • Binary files or build artifacts

How we handle your access tokens

Encrypted at rest

Fernet symmetric encryption (AES-128-CBC + HMAC-SHA256). The encryption key is an environment variable, physically separate from the database. A database leak without the key yields only ciphertext.

Never in process arguments

Tokens are passed to git clone via the GIT_ASKPASS mechanism — a helper script that reads from an environment variable. The token never appears in /proc/*/cmdline or ps aux output.

Validated at ingestion

PATs are validated against known platform prefixes (ghp_, github_pat_, glpat-) and rejected if they don't match. Catches accidental submission of wrong credentials before they reach storage.

Zero-downtime key rotation

Dual-key mechanism: set the old key as ENCRYPTION_KEY_PREVIOUS, deploy with the new key, run the migration CLI to re-encrypt all tokens. No downtime, no user interruption.

Startup validation

The API server refuses to start if the encryption key is missing. There is no silent fallback to plaintext — failure is loud and blocks deployment.

Minimum OAuth scopes

GitHub OAuth login uses only read:user, user:email, and read:org — no repository access. Scanning uses a separate token that you provide explicitly.

Session and password security

Passwords are hashed with Argon2id — 64 MB memory cost, time_cost=3, parallelism=4. Password policy enforces a 12-character minimum, rejects the top 10,000 most common passwords, and checks against the Have I Been Pwned breach database using k-anonymity (only a SHA-1 prefix is sent; the full hash is checked locally). HIBP unavailability never blocks registration.

Sessions use JWT access tokens with a 15-minute lifetime, stored in httpOnly cookies (JavaScript cannot access them). Refresh tokens rotate on every use with a 30-day maximum lifetime. All cookies are SameSite=Lax and Secure in production.

Brute-force protection: 5 login attempts per 15 minutes per IP, plus a per-email counter that locks after 10 failed attempts. The per-email counter uses a SHA-256 hash as the key — it reveals nothing about which email addresses are registered.

Production hardening

HTTPS enforced in production — startup check rejects all http:// URLs for backend, frontend, and CORS origins.
HSTS 2-year max-age with includeSubDomains and preload. Forces HTTPS at the browser level.
CSP default-src 'none'; frame-ancestors 'none' on all API responses. Prevents XSS and clickjacking.
X-Frame-Options DENY. X-Content-Type-Options: nosniff. Referrer-Policy: strict-origin-when-cross-origin.
Swagger UI disabled in production — /docs, /redoc, and /openapi.json are unavailable. Prevents endpoint enumeration.
Sentry scrubs Authorization, X-API-Key, and Cookie headers before sending events. send_default_pii=False.
Redis password required in production — startup validation rejects default credentials.
Docker all service ports bound to 127.0.0.1 — not exposed to the network.

Your data is your data

All data is scoped to a Workspace via foreign keys enforced at the database level. Every API query filters by the authenticated workspace — there is no global view.

Cross-workspace access attempts return 404 Not Found (not 403 Forbidden). This prevents an attacker from even discovering whether another workspace's resources exist.

Workspace API keys are scoped to a single workspace and cannot access any other. We run a parametrised cross-workspace isolation test suite in CI that hits every endpoint with a foreign workspace ID and asserts 404 on all of them.

Offboarding and data portability

Disconnect an organisation

The encrypted token is deleted from the database. All associated repositories, scans, dependency data, and artifacts are cascade-deleted. You should revoke the token manually at your provider (GitHub Settings / GitLab Settings).

Delete your account

30-day grace period (GDPR soft-delete). All sessions are immediately revoked. You can cancel by re-authenticating within the grace period. After 30 days, all workspace data, scans, and personal data are permanently hard-deleted.

Export your data

GET /workspaces/{id}/export returns all workspace data as JSON. Members, connected orgs, repos, scans, dependencies, artifacts, and audit events. Encrypted tokens are redacted. Rate-limited to one export per workspace per hour.

Common security questions

01 Do you store my source code?

No. Source code is cloned to a temporary directory, parsed for dependency metadata, and deleted immediately — guaranteed by a try/finally block. A background task sweeps for orphaned clones every 15 minutes as a safety net. Only dependency names, version constraints, and line numbers persist.

02 What access does Riftmap need?

For login, GitHub OAuth uses only read:user, user:email, and read:org — no repository access. For scanning, you provide a separate PAT with read-only access to repository contents and metadata. We recommend a fine-grained GitHub PAT with "Contents: Read-only" and "Metadata: Read-only", or a GitLab PAT with read_repository scope.

03 Can other workspaces see my data?

No. All data is scoped to your workspace via foreign keys enforced at the database level. Cross-workspace access attempts return 404 (not 403) to prevent even leaking the existence of other workspaces. We run a parametrised cross-workspace isolation test suite in CI that hits every endpoint with a foreign workspace ID.

04 What happens if I disconnect an organisation?

The encrypted token is deleted from the database, and all associated repositories, scans, dependency data, and artifacts are cascade-deleted. Riftmap does not automatically revoke your token at the provider — you should do this manually via your GitHub or GitLab settings.

05 How do I export my data?

GET /workspaces/{id}/export returns all workspace data as JSON — members, connected orgs, repos, scans, dependency declarations, resolved edges, artifacts, and audit events. Encrypted tokens are redacted. Rate-limited to one export per workspace per hour.

06 Is Riftmap SOC 2 certified?

Not yet. SOC 2 Type II certification is on our roadmap. In the meantime, every security claim on this page is verifiable against our codebase. We publish our security documentation openly and welcome review.

07 Can I self-host Riftmap?

Yes. Riftmap can be self-hosted via Docker Compose. When self-hosted, your data never leaves your infrastructure, and billing features are disabled. The same security controls (encryption, isolation, cleanup) apply in both modes.

Start mapping your dependencies

Connect a GitHub or GitLab organisation with a read-only token. Riftmap scans your repos, builds the dependency graph, and deletes the code. You can disconnect anytime.

Every security claim on this page is verifiable against our codebase.