Architecture

AIOS Govern sits between your AI agents and the humans accountable for their actions. Agents submit envelopes; the platform routes each one to the right approver, enforces separation of duties, records an immutable audit trail, meters usage against a license tier, and delivers the decision back over a signed webhook, a long-poll, or realtime.

Roles & the approval gate

Every signed-in human has a user_profile with a role and a status.

super_adminFull platform control, including site settings and tier configuration.
adminManages agents/keys, releases held overage, approves access requests, replays webhooks.
userActs on envelopes routed to them; submits via the agents/keys they own.

New non-admin sign-ups land status: "pending" and cannot act until an admin (with can_approve_access) approves them — the approval gate. access_requests capture a user asking for an API or MCP key (kind, requested scopes, rate limit, reason); an admin approves and fulfilment mints the key.

Accounts & teams

An account is the billing + ownership boundary: it owns folders, agents, and envelopes, and carries a license tier plus a usage counter. A team is a routing + approval group with its own owner, members, and (optionally) its own tier and usage pool — a team pool overrides the account pool when an envelope is attributed to a team. Folders organize envelopes within an account.

Agents & keys

An agent is a credential record. Keys come in two kinds: agent (REST, issued via invite / register-channel on /agents) and mcp (self-serve at /connect). The API key and webhook secret are stored only as hashes (api_key_hash, secret_hash) — the plaintext is shown once at creation. Each key carries scopes (submit / read / close / approve), an optional bound owner_user_id (used for manager routing and self-approval rules), and a status of active or revoked. A channel binds an agent to a folder; agents submit envelopes to a channel.

Envelope lifecycle & state machine

An envelope is the unit of governance. Its resting state on arrival depends on the route (a log_only / notify envelope is terminal immediately; an approval envelope rests at pending). Transitions:

pending ──approve──────────▶ approved   ─┐
        ──reject───────────▶ rejected   ─┤
        ──mark_informational▶ acknowledged┤──▶ completed
        ──request_info─────▶ needs_info   │   (audit + webhook/long-poll fire)
        ──escalate─────────▶ escalated    │
        ──delegate─────────▶ pending      │   (re-routed to another user)
                                          │
needs_info ──agent_responds▶ pending  ────┘

escalated  ──approve──────▶ approved
           ──reject───────▶ rejected

approved, rejected and acknowledged are finalizing states that roll into completed (the only terminal state), at which point completed_at is stamped and delivery fires. On request_info the agent answers via the respond endpoint to return the card to pending. Expiry follows on_timeout: escalate re-arms the countdown, while auto_approve / auto_reject / expire resolve terminally.

Routing & authority

route decides who may act, resolved at submit time into routed_to_user_id / routed_to_team_id:

log_onlyPure log; terminal on arrival, no decision.
approvalA DIFFERENT human must approve — self-approval is blocked (separation of duties).
approval_selfThe submitting key's bound user may approve their own request.
approve_managerRouted to the submitter's manager_user_id.
approve_teamAny member of team_id may approve (first responder wins).
approve_any_adminAny admin may approve.
notify_manager / notify_team_ownerFYI only, no decision (green accent).

Decisions & immutable audit

Every state change writes a decision row — actor (user / agent / system), action (approve, reject, request_info, escalate, delegate, mark_informational, agent_responds), optional comments, and a step index for multi-step rules. Decisions are append-only — the chain of who-decided-what is never mutated. A separate audit log records entity-level events for compliance review.

Licensing & held overage

license_tiers define a name, price, and a monthly_request_limit. Each submission is metered against the owning pool (a team pool overrides the account pool) and a usage_event is recorded (source api / mcp, action, IP). When the pool is over limit the envelope is still accepted but marked held: true — hidden from the inbox until an admin releases it (or the tier is upgraded). The submit response echoes a quota block (used / limit / remaining / source) so agents can self-throttle.

Decision delivery

Three mechanisms, selectable per envelope via return_mode:

Data model

Core tables, all prefixed aigos_*, scoped by account/team and protected by row-level security:

aigos_accountsBilling/ownership boundary; tier, usage counter, agent limit.
aigos_teams / aigos_team_membersRouting & approval groups with their own tier + usage pool.
aigos_user_profilesRole (user/admin/super_admin), status, manager, access-approval flag.
aigos_access_requestsRequests for api/mcp keys: scopes, rate limit, reason, decision.
aigos_agentsCredential records (kind agent/mcp): key/secret hashes, scopes, owner, status.
aigos_invitesOne-time tokens for the register-channel flow.
aigos_channelsBind an agent to a folder; envelopes are submitted to a channel.
aigos_foldersOrganize envelopes within an account.
aigos_envelopesThe governance unit: type, risk, payload, route, state, expiry, tweak fields.
aigos_envelope_tweaksRequest-changes round-trips (pending/resolved/withdrawn).
aigos_decisionsAppend-only decision/audit trail per envelope.
aigos_webhook_deliveriesOutbound delivery attempts, signatures, retry/failed state.
aigos_usage_eventsMetered submit/act events (source api/mcp) for licensing + analytics.
aigos_license_tiersTier definitions: name, price, monthly request limit.
aigos_dashboards / _widgetsUser-configurable inbox dashboards.
aigos_site_settingsSingleton: canonical domain + last editor.

A self-hosted Gateway (egress-side enforcement) is on the roadmap — its docs will live on a future page. For now, start with the Quickstart or the API reference.