Skip to main content

The trust tree

A verifier who has never heard of an organization can still decide whether to trust it, because the organization's place in the trust tree is published as signed statements that lead to one key the verifier already holds. Admitting an organization is what produces those statements.

This page explains the parts. The requests that admit an organization and publish it are in Admit an organization and publish it. How a verifier's own system fetches and checks the statements is in Read the trust tree.

OktoID publishes the tree as OpenID Federation 1.0 entity statements, so a verifier built for that specification reads it without knowing OktoID.

The anchor​

The top of the tree is the trust anchor: the governance authority itself. The setup run creates it from the deployment's answer file, admits it, and publishes it, with nobody above it to approve. On a local stack it is the organization /oktoid, and its address is https://oktoid.identity.local.oktoid.app.

A verifier trusts the tree by holding the anchor's public keys. Everything else is checked against them.

An address per organization​

An admitted organization gets an address of its own: https://<slug>.identity.<domain>, where the slug is the last part of the organization's path. /oktoid/acme becomes acme.identity.<domain>.

That address, written exactly that way, is the organization's entity identifier. It has no port, no path and no trailing slash, so comparing two identifiers as text is enough to tell whether they name the same organization.

The platform creates a signing key for each admitted organization and holds it in a hardware security module, or in the software module that stands in for one on development stacks. The private half never leaves the module. A statement names its key by the key's thumbprint, which is all a verifier ever sees of it.

Two statements​

Admission prepares two statements for an organization.

StatementSigned bySaysServed at
Entity configurationThe organization's own keyWho the organization is, which keys are its own, and which anchor vouches for ithttps://<slug>.identity.<domain>/.well-known/openid-federation
Subordinate statementThe anchor's keyThat the anchor vouches for the organization, and which keys the anchor accepts as the organization'sThe anchor's fetch address, with the organization's identifier as sub

Neither is enough alone. Anyone can publish a statement about themselves, so the entity configuration proves nothing until the anchor's statement names the same key. The anchor's statement is what carries the authority's decision.

The subordinate statement also says the organization may not vouch for anyone beneath it (max_path_length is 0). In this release only organizations directly beneath the anchor can be admitted.

A statement carries only fields on a fixed list. The organization's name is published; no person's name or address is. The anchor's statement about itself carries contact addresses, and each must be a role mailbox such as trust-office@, never a person's, because a published statement is permanent.

The chain a verifier walks​

Starting from nothing but an organization's identifier, a verifier:

  1. fetches the organization's entity configuration and checks it against the key inside it;
  2. reads which anchor it names;
  3. fetches that anchor's subordinate statement about the organization, and checks that it was signed by the anchor and names the same key;
  4. checks the anchor's own configuration against the anchor keys the verifier already holds.

Three statements, each signed, each within its dates. If any check fails, the organization is not in the tree as far as that verifier is concerned.

The statements are stored files, served through the edge. Fetching them calls no service of the platform, so the tree stays readable while the platform is being upgraded or is down.

Two decisions before anything is public​

Admission and publication are separate decisions.

Admitting records that the organization belongs in the tree. The statements are prepared and nothing is signed. A deployment can require that the person who admits is not the person who put the organization forward.

Approving publication releases the statements for signing. It is refused until every prepared statement has been previewed, and the preview shows the exact bytes that will be signed, not a summary of them. The platform checks the previews a second time at the moment of signing: it signs only if the statements are still the ones previewed, and only if the person who approved is the person who previewed.

The reason is that publication cannot be undone in the way other actions can. A verifier that fetched a statement holds a signed copy, valid until it expires. So the review sits immediately before the one step that cannot be taken back, and it is a review of bytes.

Lifetimes and renewal​

Every statement has an issue time and an expiry. The governance framework sets the lifetimes; a local stack uses 24 hours for an entity configuration and 48 hours for a subordinate statement. A lifetime is at least one hour and at most thirty days.

The platform signs each published statement again before half its lifetime has passed and replaces the served copy. A renewal says exactly what the statement it replaces said, under new dates, so it needs no approval; the platform refuses to renew with any other content.

Short lifetimes are the tree's safety margin. A statement that should no longer be trusted stops verifying, at the latest, when it expires, whatever any cache or verifier has kept. The served copy may itself be cached for a short time, at most an hour and never more than an eighth of the statement's lifetime.

The governance framework​

The anchor's entity configuration points, through policy_uri, at the governance framework: the published rulebook of the tree. It names the governing authority, the roles and what admits someone to each, the statement lifetimes, whom to contact, and where a dispute goes.

Each version of the framework is published once and never edited; a changed framework is a new version. The anchor publishes a signed manifest that lists every version with its address and the SHA-256 digest of its bytes. A verifier who trusts the anchor's key can therefore tell which rulebook applies and check that the copy it fetched is the one the anchor published.

Every accreditation records the framework version in force when the organization was put forward.

In this release the setup run publishes version 1 from the file the answer file names. No request authors a later version.

Not in this release​

  • Suspending or withdrawing an accreditation.
  • Admitting an organization beneath another admitted organization.
  • Organization types other than federation_entity, such as a credential issuer with its own published metadata.
  • Replacing an organization's signing key.
  • Trust marks, and policy the anchor applies to an organization's metadata.