Skip to content

Authentication & permissions

RingZero is built on least privilege: no single credential grants org-wide access. Every API request is authorized three ways — who is calling (the principal), what they’re allowed to do (role or scopes), and which resources they may touch (org, project, or host). A leaked CI key can, at worst, do what that one key was scoped to do — typically upload dependency snapshots to a single project — not read your findings or act as your org.

Five kinds of principal can authenticate to RingZero:

PrincipalCredentialIssued inCan do
Human userSession token (browser sign-in)Whatever their role allows, in the app and API
API keyrz_key_… bearer tokenSettings → API keysOnly its granted scopes, only on its granted projects
Registration tokenrz_reg_… bearer tokenSettings → HostsRegister new hosts — nothing else
Registered hostHost credential (managed by the sidecar)Derived automatically during registrationHeartbeat and challenge responses for that one host — nothing else
Scan GatewayGateway credential (managed by the gateway)Derived from an rz_gw_… enrollment token in Settings → GatewaysRelay registration and run scoped scan egress for hosts in its network — nothing else

Session tokens are short-lived and refreshed automatically by the app. A session’s org membership and role come from GET /v1/me; org, member, invitation, and API-key management endpoints are session-only — no API-key scope grants them. The four machine credentials are the ones you handle yourself — and each is deliberately narrow:

  • An API key never carries user-level power. It holds an explicit scope list fixed at creation, optionally restricted to specific projects.
  • A registration token can only add hosts to your org’s scan scope. It cannot read scans, findings, hosts, or anything else.
  • A host credential is created by the sidecar during registration, stored only on that host, rotated automatically, and dies with the registration. Even a fully compromised host can’t read your org’s data or register other hosts — its credential only heartbeats for itself.
  • A gateway credential is derived when a Scan Gateway enrolls, and only lets that gateway relay registration and open scoped, private-range scan egress for its own network. RingZero never routes a scan outside a gateway’s approved private scope (public-internet safety), and the credential is mTLS-pinned to one org (cross-tenant safety) — see the connectivity trust model.

Each member of an organization has exactly one role:

CapabilityOwnerAdminMemberAuditor
View scans, findings, dependencies
Trigger scans on registered hosts
Create projects, manage project settings
Issue / revoke API keys
Issue / revoke registration tokens, revoke hosts
Enroll / approve / revoke Scan Gateways
Manage members and roles
View the audit trail
Billing, org deletion, transfer ownership

Notes:

  • Member project visibility can be narrowed with teams (a member sees the projects of the teams they belong to; org-wide visibility is the default).
  • Auditor is a read-only role for compliance reviewers: full visibility including the audit trail, no ability to change anything or trigger scans.
  • Promoting someone to Admin, and any role change on an Owner, is Owner-only.

Each user belongs to one organization. RingZero has no public signup: a company requests access, we send account- creation details, and we provision the organization with a first Owner. Everyone else joins by redeeming an invitation — an account that hasn’t redeemed one belongs to no organization and can’t see any data.

  • Invitations are created by Admins and Owners on the Organization page; inviting someone as Admin is Owner-only, and the Owner role is never invitable.
  • An invitation is email-bound, single-use, and expires after 7 days (states: pendingaccepted / revoked / expired). Re-inviting a pending email revokes and replaces the earlier invite.
  • Any member can leave an org (removing your own membership); Admins and Owners can remove others — but removing (or demoting) an Owner is Owner-only, and the org’s sole Owner can never be demoted or removed.

API keys are org-owned service credentials — they don’t ride on a user’s session and keep working if their creator leaves the org (the audit trail records who created what). What a key can do is fixed at creation:

ScopeGrantsNeeded by
sca:uploadUpload dependency snapshots and their embedded suppressions (POST /v1/scans/dependency-snapshots)Gradle plugin (ringzeroScan), direct snapshot integrations
scans:readRead scan status and severity countsringzeroCheck polling (coming soon), dashboards
findings:readRead finding details — CVE ids, versions, dependency pathsringzeroCheck console output (coming soon), triage tooling
deps:readRead the dependency inventoryInventory exports, internal tooling
hosts:readRead registered-host inventory and statuses (GET /v1/hosts)Fleet dashboards, drift alerts
gateways:readRead Scan Gateway inventory (GET /v1/gateways)Gateway/connectivity dashboards
mcp:uploadUpload MCP scan results and usage audit events (POST /v1/mcp/scans, POST /v1/mcp/usage-events)ringzero-mcp in CI and dev machines
mcp:readRead the MCP server inventory and pull the MCP Registry catalog (GET /v1/mcp/servers, GET /v1/mcp/registry)ringzero-mcp registry pull, MCP dashboards

Alongside scopes, every key has a project restriction: all projects or an explicit list. Both are visible on the key’s row in Settings → API keys and enforced on every request.

Rules:

  • Only Admins and Owners create keys, and a key can never be granted a capability its scopes don’t name — there is no “full access” key.
  • Keys support an optional expiry (recommended for CI: 1 year, rotate on renewal) and are revocable immediately.
  • Keys can never: manage members, issue credentials, revoke hosts, trigger scans, or read the audit trail. Those capabilities are role-gated to humans.

Every API call walks the same three checks, in order:

  1. Authenticate — is the bearer credential valid, unexpired, unrevoked? Failure → 401 invalid_token.
  2. Scope — does the principal hold the capability this endpoint needs (role capability for users, scope for keys)? Failure → 403 insufficient_scope, and the error message names the missing scope.
  3. Resource — is the target resource inside the principal’s reach (the key’s project list, the member’s team visibility, the host’s own registration)? Failure → 404 not_found — resources outside your reach are indistinguishable from resources that don’t exist.
// 403 — key is valid but lacks the scope
{
"error": {
"code": "insufficient_scope",
"message": "This endpoint requires 'findings:read'. The key has: sca:upload, scans:read."
}
}

The endpoint index lists every endpoint with its required scope.

Least-privilege setups for common integrations:

UseScopesProjectsNotes
CI build gate (Gradle ringzeroScan today; gating via ringzeroCheck coming soon)sca:upload, scans:readthe one projectThe build fails on severity counts alone; the console CVE table needs findings:read — add it only if you want that detail in CI logs. See the Gradle guide.
Upload-only pipeline (scan results reviewed in the app)sca:uploadthe one projectThe narrowest useful key — it can’t read anything back.
Security dashboard / export toolingscans:read, findings:read, deps:readas neededRead-only; can’t upload or change anything.
Fleet monitoringhosts:readall projectsWatch for hosts drifting out of the active state via GET /v1/hosts.

One key per integration, named for it (ci-acme-web, grafana-export) — so revoking one integration never breaks another, and audit entries read cleanly.

Every credential and membership event and every scan authorization is recorded: key/token issued or revoked (and by whom), org created, invitation created/accepted/revoked, member role changed or member removed, host registered/expired/revoked, gateway enrolled/approved/expired/revoked, scan authorized (and which gateway it routed through), scan halted out of scope — plus the acting principal on API requests made with keys. Owners, Admins, and Auditors can review the trail under Settings → Audit.

  • Scope keys to the minimum: one integration, one project, fewest scopes.
  • Set expiries on CI keys and rotate on a schedule, not just on incidents.
  • Store keys and tokens in a secret manager or CI secret store — never in source control.
  • Prefer the Auditor role for anyone who only needs to look.
  • Review Settings → Audit after any suspected leak — then revoke; both take effect immediately.