Archons
An Archon is a Soul Stack operator — a record in the operators registry in PostgreSQL. It has an identifier (AID), a set of roles, and a lifecycle: creation, token issuance, revocation. Records are never deleted — Archons are only revoked, so that audit references to the initiator of operations stay valid.
AID — the operator’s identifier
Section titled “AID — the operator’s identifier”The AID (Archon ID) is a stable string validated against ^[a-z0-9][a-z0-9._@-]{1,127}$:
- the first character is a lowercase letter or digit;
- then lowercase ASCII letters, digits, and the characters
. _ @ -; - length 2–128 characters.
Valid examples: archon-alice, email-like alice@corp.com, an LDAP uid such as uid-4815, ops-team. The character set is deliberately narrow and safe (no /, \, quotes, control characters, or unicode) — an AID gets embedded in filenames, JWT claims, and logs.
Bootstrapping the first Archon
Section titled “Bootstrapping the first Archon”On the cluster’s first initialization the operators registry is empty. Since the base policy is default-deny, without a special mechanism any API call would end in 403, and creating the first operator would be impossible. This chicken-and-egg problem is solved by Keeper’s own administrative subcommand:
keeper init --archon=archon-alice --config=/etc/keeper/keeper.yml \ [--credential-out=/etc/keeper/archon-credential.json]What the command does:
- Under a PostgreSQL advisory lock, it checks that the
operatorsregistry is empty. If it already has records, it refuses with a message that the cluster is initialized and which Archon exists. - Creates the first Archon with the given AID and binds it to the built-in
cluster-adminrole (permission*— full access). - Issues a JWT credential and writes it to a file with
0400permissions.
A few details that matter in operation:
- This isn’t Keeper’s “client mode”.
keeper initis an administrative subcommand: a locally installed Keeper binary initializes its own state in PostgreSQL. It does not connect to a remote Keeper. - The lock removes the HA race. If several instances run
keeper initat once, the advisory lock guarantees exactly one creates the first Archon; the rest see a non-empty registry and refuse. - The bootstrap token’s TTL is 30 days (longer than usual) so the operator has time to set up further administration. The
0400file must be stored securely — it’s the first administrator’s credential.
Protection against accidental re-bootstrap
Section titled “Protection against accidental re-bootstrap”If Keeper starts and sees the operators registry is empty, its behavior depends on an explicit flag:
- without
--initialize(or theKEEPER_INITIALIZE=truevariable) Keeper refuses to start and asks you to runkeeper initfirst; - with
--initializeKeeper starts in a waiting mode: the listeners come up, but any API/MCP call returns503untilkeeper inithas run.
This is a safeguard against a catastrophic loss of PostgreSQL: without the operator’s explicit intent, the system won’t automatically issue a new admin token.
Creating further Archons
Section titled “Creating further Archons”Every operator except the first is created through the Operator API (REST/MCP/web UI) by an Archon that holds the operator.create permission:
- a record is created in the
operatorsregistry, and on creation the API returns the new operator’s JWT; - if an operator loses its token, another Archon with the
operator.issue-tokenpermission can issue it a new one — without recreating the Archon itself.
Binding a new operator to roles is a separate step (Roles and access); a freshly created Archon with no roles has no permissions at all (default-deny).
Revocation
Section titled “Revocation”An Archon is revoked, not deleted:
- revocation is done through the Operator API with the
operator.revokepermission — the record getsrevoked_atset; - the record stays in the registry so that “who created / who changed” references (the
created_by_aid/changed_by_aidfields on other entities) remain valid for auditing; - a revoked operator is no longer issued new tokens, and its active JWT stops passing the check — revocation propagates across all cluster instances almost instantly. The token’s short TTL is an additional, natural layer of defense.
Invariant: you can’t remove the last administrator
Section titled “Invariant: you can’t remove the last administrator”The cluster must always retain at least one active Archon with effective full access (*). An operation that would break this — for example, revoking the sole cluster-admin or stripping its last *-granting role — is rejected with a 409 would-lock-out-cluster error.
The invariant accounts for every path to *: a direct role binding and a binding via a group (Synod). This is self-lockout protection — you can’t accidentally or maliciously “lock” yourself and the whole cluster out of an administrator.
See also
Section titled “See also”- Security → Identity — how an Archon proves its identity (JWT, the signing key in Vault).
- Roles and access — operator permissions and binding to roles.
- Installing from packages — bootstrapping the first operator in the context of initial setup.