← Security

Pipeline identity

Per-run tokens, secret injection, and why pipelines never need long-lived credentials.

Workload tokens

Every pipeline run gets a short-lived, Ed25519-signed JWT minted specifically for that run. The token identifies which org, team, and repo triggered the run, what the token is allowed to do, and when it expires (minutes, not months).

The token's sub claim uses the repo's UUID — not its name. If a repo is deleted and a new one is created with the same name, it gets a new UUID and a new identity. No name-recycling attacks.

Token scopes

ScopeGrants
pkg:read:{org}Pull npm packages from the org's registry
pkg:write:{org}Publish npm packages to the org's registry
img:read:{org}Pull container images
img:write:{org}/{image}Push a specific container image

Secrets

Secrets are defined at three levels. Narrower scopes override broader ones — a repo secret with the same name as an org secret wins.

ScopeVisible to
OrgAll pipelines in the org
TeamThat team's pipelines only
RepoThat repo's pipelines only

Secret names must be uppercase with underscores. They are injected as environment variables in pipeline steps using the ${{ secrets.NAME }} syntax. Values are encrypted at rest, never returned by the API, and scrubbed from logs including base64 and hex encodings.

Ephemeral signing keys

For provenance attestation, each pipeline run also gets an ephemeral Ed25519 key pair. The private key exists only for the duration of the run. The public key is embedded in a certificate signed by the platform — verifiable without trusting the runner.

Pipeline sandbox

Every pipeline step runs inside an isolated container with hard enforcement at the runtime level. This applies to every image — gittan base images, custom images, external images. The image controls what tools are available; the sandbox controls what those tools can do.

EnforcementWhat it doesWhat it prevents
Read-only root filesystemImage filesystem is immutable. Only /workspace and /tmp are writable.Installing packages at runtime (apt-get, apk add)
Network isolationInstall steps can reach package registries. Build/test steps have no outbound network.Scanning internal networks, data exfiltration, calling external services
Dropped capabilitiesNo CAP_NET_RAW, CAP_SYS_ADMIN, or other Linux capabilities.Container escape, privilege escalation, raw socket access
Resource limitsCPU, memory, and wall-clock time are bounded per step.Crypto mining, resource exhaustion, runaway processes
Step isolationEach step is a fresh container. No persistent state between steps except /workspace.Secrets leaking between unrelated steps
Tenant isolationPipelines from different orgs share nothing. No cross-tenant filesystem, network, or process visibility.One customer affecting another

The sandbox protects gittan's infrastructure and other customers. It does not protect an org from its own org owner — the org owner is the admin and can run whatever they want within their sandbox. This is the same trust boundary as any cloud provider: your admin can delete your own resources, but can never reach another customer.