Chio/Docs
LOGIN · JOIN

Provider Registry & SCIM

Look up a provider record's fields, publish records the edge and trust service share, and deprovision users through SCIM.

Reference chio@5f63e6e

On this page

A provider record names one identity source that the MCP edge and the trust service both accept: an OIDC issuer with its JWKS, an OAuth 2.0 introspection endpoint, a SCIM base URL, or a SAML identity provider.

Records live in a file-backed registry, version chio.enterprise-providers.v1, that chio mcp serve-http and chio trust serve share through --enterprise-providers-file. The oidc_jwks and oauth_introspection kinds let the edge admit bearer tokens; scim and saml records serve the trust service's enterprise federated-issue lane and its SCIM lifecycle.

Synopsis

This OIDC record admits tokens from one issuer for the chio-mcp audience and maps each token's sub claim to the principal. Field names are snake_case on the wire.

provider-okta.jsonjson
{
  "provider_id": "okta-corp",
  "kind": "oidc_jwks",
  "enabled": true,
  "provenance": {
    "configured_from": "docs-provider-registry",
    "source_ref": "scripts/transcripts/provider-registry.json",
    "trust_material_ref": "jwks:https://id.larkfield.example/oauth2/default/v1/keys"
  },
  "trust_boundary": {
    "allowed_issuers": ["https://id.larkfield.example/oauth2/default"],
    "allowed_audiences": ["chio-mcp"]
  },
  "issuer": "https://id.larkfield.example/oauth2/default",
  "discovery_url": "https://id.larkfield.example/oauth2/default/.well-known/openid-configuration",
  "jwks_url": "https://id.larkfield.example/oauth2/default/v1/keys",
  "subject_mapping": { "principal_source": "sub", "groups_field": "groups", "roles_field": "roles" }
}

Provider record fields

provider_id

stringRequired

The record's identifier and its key in the registry. Upserting a record with an existing provider_id replaces it.

Example"okta-corp"

kind

enumoidc_jwks, oauth_introspection, scim, saml

The identity source the record describes. The kind decides which endpoint fields are required.

Example"oidc_jwks"

enabled

booleanRequired

Whether the record may admit at all. A record admits only when it is enabled and its validation_errors list is empty.

provenance

objectconfigured_from, source_ref, trust_material_ref, subject_mapping_source

Where the record came from and which trust material backs it. configured_from and trust_material_ref are required; source_ref and subject_mapping_source are optional.

Example"trust_material_ref": "jwks:https://id.larkfield.example/oauth2/default/v1/keys"

trust_boundary

objectallowed_issuers, allowed_audiences, allowed_tenants, allowed_organizations

Allowlists the record's own values must fall inside. The issuer, tenant_id, and organization_id are each checked against their list; an empty list allows any value.

Example"allowed_audiences": ["chio-mcp"]

provider_profile

enumgeneric, auth0, okta, azure-ad; optional

The JWT provider profile that selects principal mapping. azure-ad maps users by oid before sub.

Example"azure-ad"

issuer, discovery_url, jwks_url

stringoidc_jwks: issuer, plus discovery_url or jwks_url

The OIDC issuer and where its keys are found. An oauth_introspection record also requires issuer.

introspection_url

stringRequired for oauth_introspection

The OAuth 2.0 token introspection endpoint.

scim_base_url

stringRequired for scim

The SCIM base URL of the provisioning source.

saml_entity_id, saml_metadata_url

stringBoth required for saml

The SAML identity provider's entity id and metadata URL.

tenant_id, organization_id

stringOptional

The tenant and organization the record is scoped to. Each must fall inside its trust_boundary allowlist.

subject_mapping

objectprincipal_source required

Which claims build the principal and the identity context: principal_source, plus optional client_id_field, object_id_field, tenant_id_field, organization_id_field, groups_field, and roles_field.

Example{ "principal_source": "sub", "groups_field": "groups" }

validation_errors

string[]Computed on upsert

Why the record is ineligible. The registry recomputes the list on every upsert; a record with errors stays listed and never admits.

Registry commands

chio trust provider upsert, list, get, and delete manage the file registry directly, or the trust service's registry through --control-url. The service exposes the same records at /v1/federation/providers and /v1/federation/providers/{provider_id}.

Publish the OIDC recordtranscript
$ chio trust provider upsert --input ./provider-okta.json \
  --enterprise-providers-file ./providers.json
provider upserted: okta-corp
exit 0
Read it backtranscript
$ chio trust provider get --provider-id okta-corp \
  --enterprise-providers-file ./providers.json
provider_id: okta-corp
kind:        "oidc_jwks"
enabled:     true
validated:   true
exit 0

validated: true means the record passed every check for its kind and may admit while it stays enabled.

Invalid records

The registry accepts an incomplete record, stores the reasons in validation_errors, and keeps it out of admission. Every record needs provider_id, provenance.configured_from, provenance.trust_material_ref, and subject_mapping.principal_source, plus the endpoint fields its kind requires. This SAML record has neither an entity id nor a metadata URL.

Publish an incomplete SAML recordtranscript
$ chio trust provider upsert --input ./provider-broken.json \
  --enterprise-providers-file ./providers.json
provider upserted: legacy-saml
exit 0
List both recordstranscript
$ chio trust provider list --enterprise-providers-file ./providers.json
providers: 2
- legacy-saml ["saml"] enabled=true valid=false
- okta-corp ["oidc_jwks"] enabled=true valid=true
exit 0
Read the invalid recordtranscript
$ chio trust provider get --provider-id legacy-saml \
  --enterprise-providers-file ./providers.json
provider_id: legacy-saml
kind:        "saml"
enabled:     true
validated:   false
exit 0

The record is listed with valid=false and reads back validated: false. It never admits a token. Each server also logs a warning when it loads the file, so an operator can diagnose the record from the registry or from the log.

SCIM lifecycle

Enterprise subject
bearerbearerverifies: key, JWKS, or introspectionoidc:<issuer>#sub:<sub>revokeddeprovision receipta1session 1a2session 2σidentity providerKMCP edgesChio subjectsubjectKeyuSCIM DELETEκsession capabilitiesρreceiptsverifiesoidc:<issuer>#sub:<sub>revokeddeprovision receipta1session 1a2session 2σidentity providerKMCP edgesChio subjectsubjectKeyuSCIM DELETEκsession capabilitiesρreceipts

Deprovisioning revokes what the subject holds

A SCIM DELETE on the trust service revokes every capability tracked for the user, appends a signed deprovision receipt, and marks the identity inactive. An inactive identity binds no new capability. Revocation.

A SCIM deprovision on the trust service reaching the Chio subject a provisioned user resolves to. Provisioning, capability binding, and the sessions that held the revoked capabilities are left out.Federate Enterprise Identity

chio trust serve --scim-lifecycle-file hosts a ScimLifecycleRegistry of ScimUserResource records at /scim/v2/Users, behind the service token. A provisioned user resolves to the same enterprise identity context the edge builds from a token (build_enterprise_identity_context_from_scim), and its subject key derives from the provider scope and the canonical principal (derive_enterprise_subject_key).

DELETE /scim/v2/Users/{user_id} revokes every capability tracked for the user that is still live, appends a signed deprovision receipt, and marks the identity inactive with its deprovision time and receipt id. An inactive identity binds no new capability. Receipts already written keep their attribution.

Source

Provider records are defined in crates/platform/chio-control-plane/src/enterprise_federation.rs, and the SCIM registry in scim_lifecycle.rs of the same crate. Token admission is on Federate Enterprise Identity.

Next: admit tokens from a registered provider

Provider Registry & SCIM · Chio Docs