Skip to main content
When you run agents across an organization, two questions never stop mattering: what can each agent reach, and who authorized it to reach that. Corbits answers both with one model. On the control plane, every capability an agent has is inert until an explicit policy turns it on, and every decision to turn it on is a durable record you can inspect. This page is the control-and-audit reference. If you lead an AI org, it shows you how to hand agents real power without handing over the keys. If you own security or compliance, it shows you where authority comes from, how it is bounded, and why the default is always deny.
This page describes the control plane: the layer that resolves every credential and authorization decision before an agent does any work. These controls are not opt-in hardening; the control plane applies them to every agent it launches. Workbench runs on the control plane and inherits them. Corbits Code does not run on the control plane, so the controls described here do not govern it.

Two primitives

Everything reduces to two things:

Credentials

The secrets an agent uses to authenticate with an outside service — an API key, an OAuth token, a certificate. Owned and stored by your organization, never discovered by the agent.

Grants

The atomic unit of authorization. Every decision the control plane makes about what an agent may do is resolved by evaluating grants. A capability with no matching grant is denied.
A capability that reaches the outside world needs both. A credential says how to authenticate; a grant says whether this principal is allowed to use it at all.

Credentials

A credential is a runtime secret an agent uses to authenticate with a provider — GitHub, OpenAI, Slack, Google Drive, an internal deployment service, an SSH bastion. Every credential belongs to a provider; there are no provider-less credentials. The provider definition is what tells the control plane how to handle the credential: its refresh behavior, its authentication method, its scope model. The credential’s type — API key, OAuth token, certificate — is a property of the credential, not something the agent chooses. From the agent’s side, it needs “access to service X,” and the control plane figures out the authentication mechanism. Agents do not select or negotiate credential types.

Resolved at launch, never at runtime

This is the principle that makes credentials auditable:
Agents never discover or look up credentials at runtime. When an agent launches, the control plane resolves the credentials it needs and hands them to the agent’s harness as part of launch. The harness holds them in memory for the agent’s lifetime and mediates every use — proxying requests with authentication attached, or injecting the credential into the runtime.
Resolution, access control, and scope validation all happen at launch time. An agent can never reach into a store and pull a secret it was not launched with. Credentials live in the control-plane credential store and are resolved into a specific agent’s harness only when that launch is authorized.
Credential secrets are encrypted at rest. Every write path seals the secret before it reaches the database, and each ciphertext is bound to its own row and column, so a value lifted from one row will not decrypt in another. Today that binding is AES-256-GCM under a single operator-provided key. It is not KMS-managed or envelope-encrypted, and we do not claim it is; the encryption seam is pluggable so a KMS implementation replaces it without touching a call site. The architectural guarantee is unchanged: credentials are resolved and scoped at launch, and agents never look them up themselves.

Two independent axes

Credentials vary along two axes that are easy to conflate. Keep them separate.
A credential can optionally be owned by a specific principal in the tenant.
  • Organizational — no principal owner. Shared across the tenant and managed by administrators. This is the company’s OpenAI key, its deploy token.
  • Personal — owned by a specific user or agent, typically created through an OAuth flow where that user authorized Corbits to act on their behalf with a third-party service.
An agent definition declares which credential a requirement should resolve to by source:
  • tenant — the tenant’s organizational credential.
  • creator — the agent author’s personal credential.
  • invoker — the user launching the agent supplies their own.
Source is about provenance of authority, not about sharing. A tenant-sourced credential is shared; an invoker-sourced one is not. Do not read “shared” as “invoker.”
Credentials also carry scopes — populated automatically for OAuth tokens, and specified by an administrator for API keys — so the control plane can match an agent’s declared requirements accurately regardless of credential type. If an agent requires a scope the credential does not declare, the credential does not match and the launch does not use it.

Using a credential requires a grant

Referencing a credential in a definition does not authorize using it. When the control plane resolves the credential an agent uses to reach its model provider, it checks that the agent’s creator holds a grant to use that specific credential: resource credential:{id}, action use, collected across the tenant ancestor chain so an inherited credential still resolves. This check is against the creator’s own authority, not the grants materialized on the running agent’s principal that the rest of this page describes. Anything short of an explicit allow withholds the secret: an ask, a deny, or no matching grant all fail closed. Launch and credential rotation share this one check, so a secret cannot reach an agent by either path without it. This closes a real gap: authoring a definition no longer confers use of the credentials it names, and an invoker cannot route around the check by pinning a provider whose credential the creator is not authorized to use: that model is simply unavailable, and the secret is never spent. Owners receive the use grant when they create a credential, and existing personal credentials were backfilled, so the gate does not lock anyone out of their own.
Gating credential use on the creator’s grant is a deliberate interim tightening, stricter than the source model (tenant, creator, invoker) strictly requires. A tenant-owned credential would normally be authorized by tenant or role policy; until that model subsumes this path, the creator’s use grant is the authoritative check.

Grants

Grants are the atomic unit of authorization. Every authorization decision the control plane makes is resolved by evaluating grants. A grant carries three fields: A grant attaches either to a role — a named bundle of grants scoped to a tenant, assigned to users and agents — or directly to a principal. System roles (owner, admin, member) are created with every tenant; admins can define custom roles on top.

How a decision is made

For any principal attempting any operation, the engine:
1

Collect

Gather every grant that applies — direct grants on the principal plus grants from all of its roles.
2

Filter

Keep only grants whose resource and action patterns match the operation.
3

Order by specificity

More specific patterns beat less specific ones — a grant on credential:crd_gdrive outranks one on *.
4

Most specific grant decides — ties break toward denial

The most specific matching grant sets the effect. When two matching grants are equally specific, the most restrictive effect wins: deny beats ask beats allow, so ambiguity always resolves toward less access.
5

No match → deny

If nothing matches, the evaluator returns no decision and the control plane fails closed, denying the operation by default.
An ask effect blocks execution and records a pending approval. The control plane pushes no prompt and assigns no one: resolving an approval is itself a grant-gated action, evaluated like any other. An approver is any principal whose grant allows resolve on the approval. That grant’s breadth sets what they can reach: a tenant-wide approval:* grant lists the whole pending queue, while a grant covering just one agent’s approvals cannot list and instead fetches each one by its id. Any such approver can approve the action once or reject it. A control-plane approval is one-time: it authorizes that action, not future ones. Any conditions on the grant that produced the ask (time windows, approval thresholds, rate limits) are evaluated as the decision is made; a grant whose conditions are unmet is skipped. How the blocked call is parked durably, resolved exactly once, and resumed without re-running the agent is the durable approval substrate, covered in Approvals. Durable “approve always” is not one of those outcomes today: the control plane’s approval path is approve-once-or-reject and does not yet support scope: "always" (it returns unsupported_scope). No app supplies a durable auto-approval over that path either. Corbits Code does offer an “always allow” that survives a restart, but it is a different mechanism at a different layer: its gate runs in its own process against approvals it persists locally, per project or globally, and it never resolves a control-plane approval. Nothing routes or notifies an approval parked here either: the queue is pull-only, and an approver finds pending work by reading it.
Fail-closed is the property compliance cares about most. There is no implicit allow, no ambient authority, no capability that works “because nobody blocked it.” Silence is denial.

Where authority comes from: requirement sources

An agent definition does not ship live grants. It ships requirements — a manifest of the capabilities it needs. At launch, the control plane resolves each requirement against real authority and materializes grants on the agent’s own principal. A definition declares credential requirements and grant requirements separately, and the two do not draw from the same sources: a credential requirement can name tenant, creator, or invoker, while a grant requirement is limited to creator and invoker. A grant requirement that names any other source is refused at launch.

tenant

Credential requirements only. The control plane resolves a credential the organization owns, one stored with no principal of its own, walking up the tenant hierarchy until it finds a match. This source resolves no grants, and a grant requirement cannot name it.

creator

The definition author delegates authority they themselves currently hold. This is the setuid model: the author’s authority travels with the definition. A creator cannot delegate what they do not have — the control plane checks at every launch.

invoker

The person launching the agent must supply it, and they cannot pass along authority that was itself delegated to them by an invoker. Materialized as a grant that expires 24 hours after launch, a fixed lifetime that does not track how long the agent actually runs.
The agent’s effective authority is what its own principal holds: the creator- and invoker-sourced grants its requirements materialized at launch, each one checked against that party’s live authority at that moment, plus any grants stamped on that principal directly or reaching it through a role it holds. Because requirements resolve fresh at every launch, revoking a creator’s or invoker’s authority changes what the next launch materializes. It does not claw back a grant already materialized on a running agent, which stands until it expires or is revoked on its own.

The thesis: inert without both

A tool is a capability that does nothing on its own.
  • A tool is inert without a grant. tool:bash needs one thing to run: a grant that allows invoke on tool:bash. No credential is involved.
  • A tool that reaches an external provider is additionally inert without a resolved, grant-authorized credential. The credential must resolve at launch, and a grant on credential:... with action use must authorize this principal to use it.
Not every tool needs a credential — only the ones that touch an outside service. But every capability the control plane governs needs a grant, without exception. This is deliberate layering. The control plane composes independent authorization layers where both must allow the operation, and the narrower of the two layers always wins. An agent’s effective capabilities are exactly the set determined by which credentials and which grants were successfully resolved. Broad credential access is worthless without a grant; a grant is worthless without a credential the launch could resolve.

Tenant hierarchy and inheritance

Authority is organized by tenant.
  • A principal is an identity within a tenant — the join between an entity and that tenant. An entity is a person or an agent. A person’s principal is their user account in that tenant; an agent gets a principal per run, rather than one standing for the definition it was deployed from. A principal by itself grants nothing; it only establishes that the entity exists in the tenant.
  • A tenant is the isolation boundary. It has a nullable parent_id, so tenants form a hierarchy of parents and sub-tenants (child tenants).
Credentials and grants behave differently here, and the difference is easy to miss:
When the control plane looks for a credential, it checks the current tenant, then walks up the parent chain until it finds a match or reaches the root. Store an organizational credential at the parent tenant and every child tenant can resolve it automatically — define your integrations once for the whole org.A child tenant can shadow a parent’s credential by creating one with the same name; the child’s takes precedence within its scope. Names are unique within a tenant, which is what makes name-based shadowing work.

A worked example

An organization stores one Google Drive credential scoped to its financial records at the org (parent) tenant — call its resource credential:crd_gdrive_financials. Because credentials walk up the hierarchy, every department inherits it: marketing, engineering, accounting all resolve the same credential. But only principals in the accounting department hold the grant that authorizes using it:
Now launch an agent in the marketing department that tries to read those financial records:
1

The credential is reachable

Walk-up resolution can find crd_gdrive_financials at the parent tenant — every department inherits it, so it is available for the marketing agent to resolve.
2

A grant is required to use it

Using that credential requires a grant: credential:crd_gdrive_financials with action use. The engine looks for one on the marketing principal and finds none — that grant lives only on accounting principals.
3

Denied, fail-closed

No matching grant means deny. Inheritance put the credential within reach; without the grant, the marketing agent is refused — whether that refusal lands at launch or at first use, the answer is no.
The moral for both buyers: possessing or inheriting a credential confers nothing. Capability stays inert until a grant authorizes its use, and the default is deny. Inheritance spreads availability; grants control permission; the two never collapse into each other.

Audit and provenance

Authorization decides what an agent may do. Provenance records what it did and makes that record verifiable rather than something you take on trust. For an agent running on the control plane, the runtime commits conversation context and audit records on its behalf. All of it lands in that agent’s own git repository, and every commit is signed using the standard SSH signature format. The result is a tamper-evident history: any commit altered after the fact no longer verifies, so a recorded action cannot be rewritten without breaking its signature. Two keys do that signing, and neither is per-agent. The hub holds one key and signs the commits it writes, such as an agent’s deployed state. A sidecar holds one key per host and signs the run commits produced by the workflows it executes. So a signature identifies the component that wrote the commit, not the individual agent behind it, and the agent’s own key is used to authenticate it to the hub rather than to author commits.
Verification uses standard git. git verify-commit checks a commit against the public key that signed it, so you can confirm authenticity yourself, outside the platform. Be precise about where that check runs today: a sidecar verifies the commits the hub sends it, and nothing on the hub verifies a commit it receives. Tamper-evidence here is a property you can check after the fact with git, not a gate the control plane enforces on the way in.
Two limits matter if you are evaluating this for compliance. The hub mints its signing key at startup and does not persist it, and no key history is kept, so commits it signed before a restart can no longer be verified against the key it holds now. And the audit records themselves are scratch: a run’s storage is deleted when the run reaches a terminal state, and the durable copy kept by the hub carries turns and metadata rather than the audit records. The control plane exposes no route for reading audit records, sets no retention window, and offers no export.That gap is narrower than it sounds: the hub keeps its own committed, append-only log of a workflow run’s orchestration events, separate from the deleted audit records, and a route exists to read it back after the run ends. What has no query surface is the per-call authorization record, not the run itself.

Transport and supply chain

Two controls sit underneath the credential and grant model. Neither decides what an agent may do; both bound who can present themselves as part of the system and what code can enter it. The sidecar connection is authenticated. Agent execution happens in a sidecar that connects back to the control plane over a WebSocket. That connection is authenticated on the handshake against the sidecar’s own identity token, which is a distinct secret from any credential the sidecar is later given to work with. The control plane stores only a digest of that identity token, never the token itself, so reading the database yields nothing that can be replayed to impersonate a sidecar. A handshake that does not resolve to a known sidecar is rejected rather than trusted on the strength of what the connecting party claims about itself. Tool packages are integrity-checked. Third-party tool packages are distributed as npm tarballs and land in a content-addressable cache keyed by a sha512 digest, so a given digest always resolves to the same bytes and a tampered or substituted tarball does not match the integrity value recorded for it. This is a property of the agent runtime’s packaging layer, documented across the platform overview, rather than a control-plane authorization decision: it governs what code can be loaded, while grants continue to govern what that code is allowed to do once loaded.

How this shows up

Platform overview

Where credentials and grants sit in the control plane, harness, and agent lifecycle.

Corbits Code

The guardrails discipline in a real coding agent — tiered permissions and hard-deny secret guards.

Workbench

The multiplayer workspace for humans and agents, running on control-plane-governed credentials and grants.