Reference

Security overview

What runs where, what leaves your network (no telemetry, no customer data), identity and access, request handling, audit, secrets, licensing and supply chain, for a procurement or security review.

SectionReference
UpdatedSeptember 27, 2026
EditionSelf-hosted Enterprise, public beta

Applies to self-hosted ShakerScan Enterprise 0.2.0-beta.23 (public beta, September 2026). Every statement below describes behaviour that exists in the product and was exercised in acceptance testing. Items marked not yet are not claimed.

What runs where

Everything runs inside the customer's environment on a Docker host the customer operates.

ComponentSourceNetwork positionData it holds
Public engine (api, worker, ui, postgres, redis)Open-source ShakerScan images, digest-pinned, AGPL-3.0Private Compose networks; no published portsTargets, credentials for authorized targets, findings, evidence, HTTP transactions
Enterprise gatewayPrivate image from the vendor registry, digest-pinned and signedThe only service reachable from the customer network, behind Caddy TLSIdentities, sessions, service tokens, audit metadata, MFA secrets (sealed), licensed-slot ledger
CaddyPublic image, digest-pinnedPorts 80/443TLS certificates

The gateway proxies every request to the engine. Workers cannot reach the API directly; the API and workers use separate database-facing networks; the storage initializer runs with no network. No container mounts the Docker socket. The gateway runs read-only as an unprivileged user with all capabilities dropped.

Data that leaves the environment

No customer data is sent anywhere by the Enterprise gateway: no telemetry, no license activation or check-in, no usage reporting. The only request the gateway makes on its own is a read-only fetch of the public engine release catalog from GitHub, when an administrator opens or requests an engine update; it sends nothing about the installation. The public engine's own outbound behaviour (target traffic, optional AI providers configured by the customer, model endpoints) is the customer's configuration and network policy. The generated deployment disables automatic retesting, attack-surface discovery defaults and the AI operations router unless the customer turns them on.

The complete outbound list for a generated deployment, for an egress allowlist:

DestinationComponentWhen
registry-1.docker.io, auth.docker.io, production.cloudflare.docker.com (Docker Hub)host Dockerpulling the pinned public engine images at install and upgrade
ghcr.io, pkg-containers.githubusercontent.comhost Dockerpulling the Enterprise gateway image with the customer's read token
api.github.com, raw.githubusercontent.com, github.com, release-assets.githubusercontent.com (repository andriyze/shakerscan)gateway, installer, updaterread-only fetch of the public engine release catalog and the pinned engine installer, at install time and when an administrator opens or requests an engine update
install.shakerscan.comhostthe public engine installer, only on the manual install and restore paths
api.github.com and the Sigstore public-good services (Rekor transparency log, TUF root)cosign and gh on the hostverifying the gateway signature, SBOM attestation and engine build attestations at install and before an upgrade
acme-v02.api.letsencrypt.org and the ACME HTTP challenge inbound on port 80Caddyonly when no customer certificate was given to prepare
the OIDC issuer's discovery, authorization, token, JWKS and userinfo endpointsgatewaysign-in, when OIDC is configured (SHAKERSCAN_ENTERPRISE_OIDC_ENDPOINT_HOSTS pins them)
the scan targets the customer authorizesengine workersscanning; the workers pin each target's resolved addresses for the run
AI provider or model endpoints the customer configuresengineonly if configured; off in the generated deployment
a private interactsh server the customer configuresengineonly if configured; the tools run with -no-interactsh otherwise

The scanner tools run with update checks disabled; templates and vulnerability databases are baked into the pinned images, so nothing is fetched at scan time. Proxy environment variables are ignored by the gateway's and the engine's HTTP clients by design (trust_env=False), so no proxy can ever sit between the gateway and the engine. A corporate proxy is configured explicitly instead (prepare --outbound-proxy): Caddy's ACME client and the gateway's calls to the identity provider go through it; the engine's target traffic does not and must be allowed directly at the firewall; image pulls follow the Docker daemon's proxy configuration.

Identity and access

  • Single sign-on: OpenID Connect authorization code with PKCE, one-use state bound to the browser, nonce check, signed ID-token validation (RS256, ES256), exact issuer match, HTTPS-only provider endpoints restricted to reviewed hosts. Requires the authorization-code flow with S256 PKCE, RS256 or ES256 ID tokens, and client_secret_basic or client_secret_post. Validated with Okta and Keycloak (Okta guide); other providers, such as Microsoft Entra ID, use the same standard flow. Two-step verification for provider accounts is the provider's policy. An administrator configures single sign-on in the console (issuer, client, sealed client secret, group-to-role table) and runs a test sign-in at the provider before saving; saved settings apply without a restart and are audited.
  • Admission: an identity is admitted by its exact subject or by a deliberate first-sign-in group-to-role mapping. Local role changes are authoritative; removing an IdP group does not remove local access (disable the identity in the console). No SCIM (not yet).
  • Roles: viewer (read findings, evidence, scans, targets), operator (start scans, manage credentials and collections), admin (identities, tokens, audit, license). Enforced per request by method and path allowlists; unreviewed engine routes are denied.
  • Local accounts: Argon2id password hashing, minimum 14 characters, throttled sign-in, authenticator-app two-step verification with per-code replay protection. Policy can require two-step verification for administrators or all local users; a required-but-unenrolled session can reach only the enrollment screen. Ten single-use recovery codes, shown once, replace a lost passkey or authenticator; the operator's server-side reset-mfa and reset-password commands remain the break-glass path. Accounts can be created by one-time invitation links, so the person chooses their own password; an administrator can issue a one-time password-reset code (shown once, valid for an hour) without ever choosing or learning the password.
  • Passkeys for local accounts: WebAuthn, user verification required, bound to the gateway's hostname, signature counters checked, single-use server-side challenges. A passkey satisfies the two-step policy on its own; an account with a passkey and no authenticator app cannot sign in with its password alone.
  • Service tokens: issued to service identities, shown once, stored hashed, viewer or operator scope, at most 90 days, revocable individually, never able to administer or open the UI.
  • Sessions: opaque server-side sessions, __Host- secure cookies, one-hour absolute and fifteen-minute idle limits by default, bound to the password credential verified at sign-in. Role, password or factor changes revoke sessions. No provider back-channel logout (not yet).

Request handling

  • Only reviewed request headers are forwarded; cookies, bearer tokens and forwarded-host headers never cross the gateway boundary. Upstream cookies are dropped.
  • Browser mutations require a same-origin Origin header; Enterprise administration also requires a CSRF token. Engine mutations must be JSON.
  • Evidence and other engine responses are served with a sandboxing Content-Security-Policy and an attachment disposition for non-JSON media, so downloaded evidence cannot execute as a page.
  • Streaming responses re-check the session every two seconds and stop when it is revoked.
  • Request and response sizes and upstream timeouts are bounded.
  • Active work needs a target authorization on the engine. The gateway records it on the submitter's behalf, once per target, naming the operator or administrator; the audit shows who authorized which target and when. The engine's own gate still decides, and the gateway never fabricates a receipt id.

Audit

Administrative actions, sign-in outcomes, engine requests and responses (method and path, never bodies, query strings, tokens or passwords) are recorded with actor and timestamp, viewable in the console and exportable as NDJSON. The audit store is on the host and is not tamper-proof against a host administrator (remote streaming and retention policies not yet).

Secrets and keys

SecretWhereProtection
PasswordsGateway state volumeArgon2id hashes only
Sessions, service tokensGateway state volumeSHA-256 digests only
Authenticator secretsGateway state volumeAES-GCM sealed with a 32-byte key kept on the read-only secrets mount, outside the state volume
OIDC client secret, CA bundle, licenseCustomer secrets mount, read-onlyFile permissions for the gateway user only
Target credentials, evidencePublic engine (PostgreSQL, results directory)The public engine's own controls

Identity backups are AES-GCM encrypted under a passphrase-derived key (scrypt) and include the MFA sealing key; restores are create-only and revoke every session and token.

Licensing

Offline. A license is an Ed25519-signed token bound to the installation id and verified against the vendor key embedded in the package. It limits concurrent scans; the gateway reserves a slot before each scan and refuses submissions beyond the allowance. Expiry blocks new scans only; sign-in, administration, existing results and cancellation continue. A customer-attested usage summary can be exported for renewal. No network licensing, no phone-home.

Supply chain

Enterprise images are built from a version tag by a CI workflow that runs the test suite, start-tests the exact image, pushes it to a private registry, signs the digest with Sigstore keyless signing and attaches an SPDX SBOM attestation. Publication fails before anything is pushed or signed if the image has a fixed high or critical vulnerability (Trivy). Customers deploy by digest and can verify the signature and SBOM with cosign before starting anything; the kit's verify.sh runs these checks and the engine images' build attestations in one command, and the installer runs it. Engine images are pulled by digest from the public release lock file.

Operations

Create-only deployment generation, an upgrade command that keeps data and refuses downgrades, versioned state with pre-migration snapshots, and scripted backup and restore covering the engine database, evidence, encrypted identity metadata and deployment files (restore drill executed on 2026-09-12). Single-process gateway; high availability (not yet). Kubernetes packaging (not yet). An ECS Fargate evaluation layout exists and was exercised; it is not the supported production posture.

Known limitations to state in a questionnaire

One organization per installation, no project-level isolation between teams; no SCIM; no provider logout; audit is local only; HA and Kubernetes are not delivered; a single Linux Compose host (Ubuntu 24.04 LTS or 26.04, x86_64) is the supported target.