Internet-Draft OIDFed Node Admin August 2026
Kodden Expires 2 March 2027 [Page]
Workgroup:
Independent Submission
Internet-Draft:
draft-kodden-oidfed-admin-00
Published:
Intended Status:
Informational
Expires:
Author:
H.M. Kodden, Ed.
SURF

OpenID Federation Node Administration Protocol

Abstract

This document specifies a compact HTTP application programming interface for administering an OpenID Federation node. The interface manages the operator-controlled inputs from which a node produces the Entity Configurations, Subordinate Statements, Trust Marks, and Federation Entity Keys defined by OpenID Federation 1.1. It does not replace the public federation protocol. It is the management plane used by operators and control-plane software to configure what that protocol publishes.

The design is document-oriented. Operators read and write the same JSON objects OpenID Federation already defines, rather than a large set of per-claim endpoints. Five resources cover node identity, Federation Entity Keys, the node's Entity Configuration, Immediate Subordinates, and Trust Mark issuance.

Status of This Memo

This Internet-Draft is submitted in full conformance with the provisions of BCP 78 and BCP 79.

Internet-Drafts are working documents of the Internet Engineering Task Force (IETF). Note that other groups may also distribute working documents as Internet-Drafts. The list of current Internet-Drafts is at https://datatracker.ietf.org/drafts/current/.

Internet-Drafts are draft documents valid for a maximum of six months and may be updated, replaced, or obsoleted by other documents at any time. It is inappropriate to use Internet-Drafts as reference material or to cite them other than as "work in progress."

This Internet-Draft will expire on 2 March 2027.

Table of Contents

1. Introduction

OpenID Federation 1.1 [OIDF.Federation] defines how Federation Entities publish signed Entity Statements, build Trust Chains, apply metadata policies, and issue Trust Marks. Those mechanisms are the public protocol plane: any relying party on the Internet can fetch /.well-known/openid-federation, call federation_fetch_endpoint, and resolve a Trust Chain.

The specification does not define how an operator configures a node so that those public artifacts exist. In practice, Trust Anchors, Intermediate Entities, Leaf Entities, and Trust Mark Issuers are administered through vendor-specific HTTP APIs. Existing implementations [Sphereon.Admin], [GEANT.Admin], [Gateway.Admin], and [SURF.OIDFed] expose dozens of fine-grained endpoints, one for each nested claim. That style is convenient for some user interfaces. It is a poor protocol: it duplicates the OpenID Federation data model, drifts as the federation specification evolves, and forces every control plane to learn a different surface.

This document specifies a single, compact administration protocol that is strictly aligned with OpenID Federation 1.1:

The result is a small, implementable API that Leaf nodes, Intermediates, Trust Anchors, and Trust Mark Issuers can share, advertising which resources they actually support.

1.1. Applicability

This protocol is intended for:

  • federation operators administering a Trust Anchor or Intermediate;
  • organization administrators administering a Leaf Entity;
  • Trust Mark Issuers granting and revoking Trust Marks;
  • control-plane software, registries, and operator user interfaces that manage one or more nodes.

This protocol is not intended to replace Trust Chain resolution, Automatic or Explicit Registration, or any other public federation endpoint. Clients that only need to consume federation data MUST use [OIDF.Federation] and MUST NOT require this API.

1.2. Notational Conventions

The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in BCP 14 [RFC2119] [RFC8174] when, and only when, they appear in all capitals, as shown here.

JSON object member names are case-sensitive. This document uses the JSON data model of [RFC8259]. HTTP terminology follows [RFC9110]. URI syntax follows [RFC3986].

Unless stated otherwise, examples are non-normative.

2. Terminology

This document uses the terms Entity, Entity Identifier, Entity Configuration, Entity Statement, Entity Type, Federation Entity Keys, Immediate Superior, Immediate Subordinate, Intermediate Entity, Leaf Entity, metadata, metadata policy, Subordinate Statement, Trust Anchor, Trust Chain, Trust Mark, Trust Mark Issuer, and Trust Mark Owner as defined in [OIDF.Federation].

This document also uses the following terms:

Administration API:
The HTTP API specified in this document.
Administration Server:
The HTTP origin that serves the Administration API for one Federation Entity (one node).
Node:
A deployed Federation Entity that publishes an Entity Configuration and, depending on role, Subordinate Statements and Trust Marks.
Admin Document:
A JSON object that an operator reads or writes through the Administration API. An Admin Document contains OpenID Federation claims plus a small set of administration-only members (Section 9.2).
Protocol Plane:
The public OpenID Federation endpoints defined in Sections 8 and 9 of [OIDF.Federation], including /.well-known/openid-federation.
Status:
An administration-only life-cycle value that controls whether a configured object is currently published on the Protocol Plane.

3. Architecture

A node has two HTTP surfaces. The Protocol Plane is defined entirely by [OIDF.Federation]. It serves Entity Configurations, Subordinate Statements, Trust Marks, and related federation endpoints to unauthenticated or private_key_jwt-authenticated federation participants.

The Administration Plane is defined by this document. It is a confidential HTTP API used by operators and control-plane clients to create, update, suspend, and revoke the inputs from which the Protocol Plane is generated.

 Operator / Control Plane
          |
          |  Administration API (this document)
          |  authenticated, confidential
          v
   +------------+         signs         +----------------+
   | Admin docs | --------------------> | Protocol Plane |
   | Keys       |  Entity Config        | /.well-known/  |
   | Status     |  Subord. Statement    | fetch / list   |
   |            |  Trust Mark JWT       | resolve / TM   |
   +------------+                       +----------------+
          ^                                     |
          |                                     v
   Administration Server             Federation participants
Figure 1: Administration Plane and Protocol Plane

A successful mutating Administration API request MUST leave the Protocol Plane consistent with the resulting Admin Documents before the success response is returned, with the exception of key rollover grace periods described in Section 11. Implementations MAY sign new Entity Statements lazily, provided that the next Protocol Plane response reflects the update.

This document does not specify multi-node orchestration, operator identity providers, or a federation-wide registry. Those are deployment concerns (Section 17).

4. Node Initialization

A node is initialized when it has an Entity Identifier and at least one signing-capable Federation Entity Key (the server holds the private key or can invoke a KMS to use it).

The Entity Identifier is established by local configuration (for example a configuration file or container image) or by the first successful PUT {base}/configuration whose body includes entity_id. After initialization the server MUST reject any write that would change entity_id (400 with problem type invalid_request).

GET {base} MUST succeed once the Administration Server is listening, including before initialization. Before the Entity Identifier is set, the Node document omits entity_id and signing_kid.

Requests that require a signature — publishing an Entity Configuration or Subordinate Statement, or issuing a Trust Mark — MUST fail with 409 and problem type not_initialized until initialization is complete.

5. Node Roles and Capabilities

A node plays one or more of the roles defined by [OIDF.Federation]:

The resolver role means the node publishes federation_resolve_endpoint in its Entity Configuration, typically under metadata.federation_entity. This document does not define administration of resolver state such as cached Trust Chains or the set of Trust Anchors a resolver uses. Those remain Protocol Plane behavior and local configuration ([OIDF.Federation], Sections 8.3 and 10.6). A node that is only a resolver MUST implement Node, Keys, and Entity Configuration. It MUST return unsupported_resource for Subordinates and Trust Marks unless it also plays a Superior or issuer role.

Roles determine which Administration API resources a node MUST implement. A node that is only a Leaf MUST implement Node, Keys, and Entity Configuration. A node that is a Superior MUST additionally implement Subordinates. A node that issues Trust Marks MUST implement Trust Marks.

The node advertises implemented resources in the Node resource (Section 10). Clients MUST query that resource and MUST NOT assume that every node implements every resource.

6. Protocol Overview

The Administration API is a set of HTTPS resources under a single base path. The default base path is /admin/v1. Servers MAY use a different base path; clients discover it from the Node resource or from deployment configuration.

Five resources constitute the API:

Table 1: Administration API resources
Resource Path Purpose
Node {base} Identity, roles, capabilities
Keys {base}/keys Federation Entity Keys
Entity Configuration {base}/configuration Self-asserted Admin Document
Subordinates {base}/subordinates Immediate Subordinate Admin Documents
Trust Marks {base}/trust-marks Trust Mark issuance and subject grants

Each collection uses the HTTP methods in [RFC9110] with the following uniform meaning:

Signed protocol artifacts are available as sub-resources that return the JWT the node currently publishes:

That is the entire API. Nested claim paths such as /subordinates/{id}/metadata-policies/{entityType}/{claim}/{operator} are deliberately omitted. Operators who need to change one field send a JSON Merge Patch against the document that contains it.

7. Identifiers and Paths

A node's Entity Identifier is the iss / sub value of its Entity Configuration. It is immutable for the lifetime of the node after initialization.

Immediate Subordinates and Trust Mark subjects are addressed by their Entity Identifier. Trust Mark types are addressed by their trust_mark_type URI.

When an Entity Identifier or Trust Mark type appears as a path segment, it MUST be percent-encoded as a single segment per [RFC3986]. Clients MUST encode the entire identifier, including scheme, :, /, and ?. Servers MUST decode exactly one path segment.

GET /admin/v1/subordinates/https%3A%2F%2Fop.example.org
Figure 2: Percent-encoded subordinate path

Servers MAY also accept an opaque server-assigned id as an alias. If they do, the Admin Document MUST still include the entity_id member, and listing responses MUST include both identifiers.

JSON Web Key kid values used as path segments MUST be percent-encoded.

8. Authentication and Transport

The Administration API MUST be served over HTTPS [RFC9110]. Servers and clients MUST verify TLS server identity as specified in [RFC9525].

Every request except OPTIONS CORS preflight (if offered) MUST be authenticated. This specification does not mandate a single authentication scheme. Servers MUST support at least one of:

Servers MAY additionally support mutual TLS or HTTP Basic authentication for constrained deployments. Servers MUST NOT accept unauthenticated mutating requests.

Authorization — which operators may create subordinates, rotate keys, or issue Trust Marks — is out of scope. Deployments SHOULD apply least-privilege roles and SHOULD record an audit trail of mutating requests.

9. Common Conventions

9.1. Media Types

Unless a section specifies otherwise:

  • Request and response bodies use application/json [RFC8259].
  • PATCH requests use application/merge-patch+json [RFC7396].
  • Signed Entity Statements are returned as application/entity-statement+jwt [OIDF.Federation].
  • Signed Trust Marks are returned as application/trust-mark+jwt [OIDF.Federation].
  • Errors use application/problem+json [RFC9457] (Section 15).

Except in JSON Merge Patch request bodies ([RFC7396]), Admin Documents, Key Documents, list responses, and error bodies MUST NOT use the JSON value null. A member that does not apply is omitted. This matches the prohibition on null in Entity metadata ([OIDF.Federation], Section 5).

9.2. Administration-Only Members

Admin Documents MAY contain the following members in addition to the OpenID Federation claims of the corresponding artifact. These members MUST NOT appear in published Entity Statements or Trust Marks.

entity_id (string):
The Entity Identifier. REQUIRED on Subordinate and Trust Mark subject documents. On the Entity Configuration document it equals the node's Entity Identifier.
status (string):
For subordinates and Trust Mark grants: one of pending, active, suspended, or revoked. Default active. For keys: one of active, retiring, or revoked. See Section 9.3.
lifetime (number):
Suggested lifetime in seconds used by the server when computing the exp claim of the next signed artifact. If omitted, the server uses a locally configured default.
updated_at (number):
Seconds since the epoch at which the Admin Document was last written. Assigned by the server. Clients MUST ignore this member on write.
etag (string):
Opaque revision tag. Assigned by the server. Clients MUST ignore this member on write and SHOULD send it as If-Match on subsequent writes.

Unknown members that are not OpenID Federation claims and are not defined here MUST be ignored on read and MUST be preserved across PATCH if the server stored them, unless the patch sets the member to null.

9.3. Status and Publication

status controls Protocol Plane visibility. A Subordinate Statement or Trust Mark MUST NOT be published until live verification has succeeded (Section 9.8).

pending:
Bootstrap state for subordinates and Trust Mark grants when the subject is not yet online. The configuration is retained. The object MUST NOT be published. Keys do not use pending.
active:
The object is published. Subordinates appear in federation_list_endpoint and are returned by federation_fetch_endpoint. Trust Marks are issued and validate at federation_trust_mark_status_endpoint. Keys with active status are eligible for signing and appear in the published jwks.
suspended:
The configuration is retained. The object MUST NOT be published on the Protocol Plane. Fetch and list behave as if the object did not exist. A later transition to active republishes it after live verification.
revoked:
Terminal state. The object MUST NOT be published. A subsequent PUT or POST with the same identifier is a new object, not a resurrection of the revoked one. Servers MAY retain revoked records for audit.
  pending --> active <--> suspended
     |          |            |
     +------> revoked <------+
Figure 3: Allowed status transitions

pending and suspended MAY transition to active only after live verification succeeds. revoked MUST NOT return to pending, active, or suspended. DELETE is equivalent to transitioning to revoked and then removing the record from ordinary list results. Servers MAY keep pending or revoked objects visible in list results when the client passes the corresponding status query.

OpenID Federation 1.1 does not define a revocation protocol ([OIDF.Federation], Section 11.4). Status is an administration control that causes the node to stop publishing the corresponding artifact so that Trust Chains expire or fail to refresh.

9.4. Concurrency

Servers MUST return an ETag header on every successful GET, PUT, POST, and PATCH of an Admin Document. Clients SHOULD send If-Match on PUT, PATCH, and DELETE. If If-Match does not match the current revision, the server MUST return 412 Precondition Failed.

9.5. Pagination and Filtering

List endpoints return:

{
  "items": [
    {
      "entity_id": "https://op.example.org",
      "status": "active"
    }
  ],
  "next": "LjI"
}

limit (query, positive integer) is OPTIONAL. Servers MUST honor values up to an implementation-defined maximum and MUST NOT return more items than requested. cursor (query, string) is OPTIONAL and continues a previous page. When no further page exists, the next member is omitted.

List endpoints MAY support:

  • status — filter by administration status;
  • entity_type — filter subordinates whose metadata contains that Entity Type Identifier;
  • q — implementation-defined substring match on entity_id.

9.6. JSON Merge Patch

PATCH uses JSON Merge Patch [RFC7396]. A member set to null is deleted. Arrays are replaced, not merged. To change one element of authority_hints or trust_marks, the client sends the complete replacement array.

OpenID Federation objects such as metadata, metadata_policy, and constraints are JSON objects and therefore merge recursively. This is the intended way to change a single metadata parameter or a single policy operator.

9.7. Validation Against OpenID Federation

On every write of an Admin Document the server MUST validate that the OpenID Federation claims would produce a syntactically valid artifact under [OIDF.Federation]:

  • Entity Configuration writes: claims in Sections 3.1.1 and 3.1.2.
  • Subordinate writes: claims in Sections 3.1.1 and 3.1.3, including metadata_policy (Section 6.1) and constraints (Section 6.2).
  • Trust Mark writes: claims in Section 7.1.

The server MUST reject writes that violate those rules with 400 and problem type invalid_federation_claim (Section 15). The server MUST NOT accept iss or sub values that conflict with the node's Entity Identifier or the subordinate's entity_id. The server assigns iss, sub, iat, and exp when it signs.

The server MUST reject a Leaf configuration that includes federation_fetch_endpoint or federation_list_endpoint, and MUST reject a Superior configuration that omits them, consistent with Section 5.1.1 of [OIDF.Federation].

9.8. Live Verification Before Publication

Claim validation (Section 9.7) is not enough to add another Entity to the federation. A write that would publish a Subordinate Statement or issue a Trust Mark MUST also live-check the subject before the Protocol Plane changes. Keys are local to the node: generate and import validate the public JWK and MUST NOT publish private material; they have no remote subject to fetch.

The server MUST perform live verification when any of the following holds:

  • The resulting status is active and the object was not already active (create, or transition from pending or suspended).
  • The resulting status is active and the write changes a subordinate's entity_id or jwks.
  • A Trust Mark grant is created or replaced with resulting status active.

A metadata-only change to an already-active subordinate does not require a new live check. Claim validation still applies.

Subordinate live verification: the server MUST fetch the subject's Entity Configuration and verify that the presented jwks matches the subject's Federation Entity Keys and that the node's Entity Identifier appears in the subject's authority_hints. naming_constraints and allowed_entity_types MUST still be applied when present.

Trust Mark grant live verification: the server MUST verify that a Trust Chain to the subject can be constructed under at least one Trust Anchor this node trusts.

On failure, including when the subject cannot be reached, the server MUST return 422 with problem type subject_mismatch and MUST NOT publish or replace the Protocol Plane artifact. A stored pending or suspended document is left unchanged.

Query parameter verify and body member verify have the same meaning. They default to true. If both are present they MUST agree. verify=false is accepted only when the resulting status is not active; otherwise the server MUST return 400 with problem type invalid_request.

If the subject is not yet online, the operator writes status pending. The document is stored and MUST NOT be published. jwks MAY be omitted while pending and is REQUIRED when the subordinate becomes active. The later transition to active MUST live-verify.

10. Node Resource

10.1. GET {base}

Returns the node's identity and capabilities.

Response 200:

{
  "entity_id": "https://ta.example.org",
  "roles": ["trust_anchor", "trust_mark_issuer"],
  "base": "/admin/v1",
  "spec": "draft-kodden-oidfed-admin-00",
  "signing_kid": "NzbLsXh8uDCcd-6MNwXF4W_7noWXFZAfHkxZsRGC9Xs",
  "implementation": {
    "name": "example-node",
    "version": "1.4.2"
  },
  "capabilities": {
    "keys": ["list", "create", "rotate", "delete"],
    "configuration": ["read", "replace", "patch"],
    "subordinates": ["list", "create", "read", "replace",
                     "patch", "delete", "status", "statement"],
    "trust_marks": ["list", "create", "read", "replace",
                    "delete", "grant", "status", "token"]
  }
}

roles MUST be consistent with the Entity Types present in the published Entity Configuration. capabilities lists the operations the server implements for each resource. Clients MUST treat a missing resource key as "not implemented".

GET {base} is the capability discovery document. There is no separate /capabilities resource.

11. Federation Entity Keys

Federation Entity Keys are the keys whose public halves appear in the jwks claim of the node's Entity Configuration as a JSON Web Key Set [RFC7517] and that sign Entity Statements and Trust Marks as JSON Web Signatures [RFC7515] ([OIDF.Federation], Sections 3.1.1 and 7). Entity Statements and Trust Marks are JWTs [RFC7519]. Protocol keys carried under Entity Type metadata are not managed here; they are ordinary members of metadata.

11.1. Key Document

{
  "kid": "NzbLsXh8uDCcd-6MNwXF4W_7noWXFZAfHkxZsRGC9Xs",
  "status": "active",
  "signing": true,
  "alg": "ES256",
  "kty": "EC",
  "public_jwk": {
    "kty": "EC",
    "crv": "P-256",
    "kid": "NzbLsXh8uDCcd-6MNwXF4W_7noWXFZAfHkxZsRGC9Xs",
    "x": "f83OJ3D2xF1Bg8vub9tLe1gHMzV76e8Tus9uPHvRVEU",
    "y": "x_FEzRu9m36HLN_tue659LNpXW6pCyStikYjKIWI5a0"
  },
  "created_at": 1756454400
}

kid SHOULD be the JWK Thumbprint using SHA-256 [RFC7638], as recommended by [OIDF.Federation]. public_jwk MUST contain only public members. Private key material MUST NOT appear in any Administration API response. not_after is an OPTIONAL expiration time in seconds since the epoch. If the key does not expire, the member is omitted.

status for keys is active, retiring, or revoked:

  • active — present in the published jwks; eligible to become the signing key.
  • retiring — present in the published jwks; MUST NOT be newly selected as the signing key. It MAY remain the signing key until a rollover switch completes (Section 11.6). Used during rollover ([OIDF.Federation], Section 11.2).
  • revoked — absent from the current jwks; MAY appear at federation_historical_keys_endpoint.

Exactly one key is the node's signing key at any time, or none if no signing-capable key exists. signing is true on that Key Document. The Node document's signing_kid is that key's kid, and is omitted when none exists.

If several keys are active and signing-capable, the server MUST choose exactly one as the signing key. It is RECOMMENDED that this be the most recently created such key. Clients MUST read signing_kid or signing rather than inferring from status alone.

11.2. GET {base}/keys

Returns a page of Key Documents. Query status MAY filter the list.

11.3. POST {base}/keys

Creates a key. The request is one of two shapes. Generate (server holds the private key):

{
  "generate": {
    "kty": "EC",
    "crv": "P-256",
    "alg": "ES256"
  }
}

Import (private key is held elsewhere; only the public JWK is registered):

{
  "import": {
    "kty": "EC",
    "crv": "P-256",
    "x": "...",
    "y": "...",
    "alg": "ES256"
  }
}

Response 201 with the Key Document and a Location header. The new public JWK MUST appear in the next published Entity Configuration jwks.

A newly created key that the server can sign with becomes the signing key if none exists; otherwise it is active with signing false. If the node has no signing-capable active key after this request, the server MUST still accept an import, but requests that require a signature MUST return 409 with problem type not_initialized until a signing key is available.

11.4. GET {base}/keys/{kid}

Returns the Key Document. 404 if unknown.

11.5. DELETE {base}/keys/{kid}

Transitions the key to revoked and removes it from the published jwks. The server MUST reject the request with 409 and problem type last_signing_key if this is the last active or retiring key that can sign.

If the deleted key was the signing key and another signing-capable active key exists, the server MUST select a replacement (RECOMMENDED: the most recently created) and update signing_kid.

11.6. POST {base}/keys/{kid}/rotate

Performs a Federation key rollover for {kid} as specified in [OIDF.Federation], Section 11:

  1. Generate or import a new key (request body is the same as POST {base}/keys).
  2. Add the new key to the published jwks with status=active.
  3. Set the old key's status to retiring.
  4. The old key remains the signing key (signing true, status retiring) until an OPTIONAL switch_after (seconds) elapses, or until the server applies a local switch if switch_after is omitted or zero. After the switch the new key has signing true and the old key is retiring with signing false. The client MAY later DELETE the old key.
{
  "generate": { "kty": "EC", "crv": "P-256", "alg": "ES256" },
  "switch_after": 86400
}

Response 201 with the new Key Document. The old key remains addressable at its original {kid}.

12. Entity Configuration

The Entity Configuration Admin Document is the operator-editable content of the node's self-signed Entity Statement. The server supplies iss, sub, iat, exp, and jwks when it signs. The operator supplies the remaining Entity Configuration claims.

12.1. Configuration Document

{
  "entity_id": "https://ta.example.org",
  "lifetime": 86400,
  "authority_hints": [],
  "metadata": {
    "federation_entity": {
      "organization_name": "Example Trust Anchor",
      "federation_fetch_endpoint": "https://ta.example.org/fetch",
      "federation_list_endpoint": "https://ta.example.org/list",
      "federation_trust_mark_status_endpoint":
        "https://ta.example.org/trust-mark-status"
    }
  },
  "trust_marks": [],
  "trust_mark_issuers": {
    "https://ta.example.org/marks/research": [
      "https://ta.example.org"
    ]
  },
  "trust_mark_owners": {}
}

Members authority_hints, trust_anchor_hints, metadata, trust_marks, trust_mark_issuers, trust_mark_owners, and crit have the meanings and constraints of [OIDF.Federation], Sections 3.1.1 and 3.1.2.

trust_marks lists Trust Marks the node holds about itself. The server MUST copy these objects unchanged into the published Entity Configuration. It MUST NOT resign another issuer's Trust Mark.

trust_mark_issuers and trust_mark_owners are meaningful only on a Trust Anchor. Servers MUST reject them on a node whose roles do not include trust_anchor.

A Leaf or Intermediate MUST include a non-empty authority_hints array. A Trust Anchor with no Superior MUST omit authority_hints from the published Entity Configuration.

12.2. GET {base}/configuration

Returns the Configuration Document.

12.3. PUT {base}/configuration

Replaces the Configuration Document. Omitted optional members are cleared. Response 200. The server MUST NOT allow entity_id to change after initialization (Section 4). If entity_id is not yet set, this request MAY establish it.

12.4. PATCH {base}/configuration

Merge-patches the Configuration Document. Response 200.

12.5. GET {base}/configuration/statement

Returns the currently published Entity Configuration JWT with Content-Type: application/entity-statement+jwt. This MUST be byte-for-byte the document served at /.well-known/openid-federation.

13. Subordinates

The Subordinates resource is implemented by Trust Anchors and Intermediate Entities. Leaf nodes MUST return 404 with problem type unsupported_resource for every path under {base}/subordinates.

A Subordinate Admin Document is the operator-editable content of the Subordinate Statement the node will sign about one Immediate Subordinate.

13.1. Subordinate Document

{
  "entity_id": "https://op.example.org",
  "status": "active",
  "lifetime": 86400,
  "jwks": {
    "keys": [
      {
        "kty": "EC",
        "crv": "P-256",
        "kid": "op-fed-1",
        "x": "f83OJ3D2xF1Bg8vub9tLe1gHMzV76e8Tus9uPHvRVEU",
        "y": "x_FEzRu9m36HLN_tue659LNpXW6pCyStikYjKIWI5a0"
      }
    ]
  },
  "metadata": {
    "openid_provider": { "organization_name": "Example University" }
  },
  "metadata_policy": {
    "openid_relying_party": {
      "id_token_signed_response_alg": {
        "default": "ES256",
        "one_of": ["ES256", "ES384", "ES512"]
      }
    }
  },
  "constraints": {
    "max_path_length": 1,
    "naming_constraints": { "permitted": [".example.org"] },
    "allowed_entity_types": [
      "openid_provider",
      "openid_relying_party"
    ]
  }
}

jwks is REQUIRED for an active subordinate and is the subject's Federation Entity Keys. It MAY be omitted while status is pending. The server assigns iss, sub, iat, and exp when it signs. The server MAY add source_endpoint set to its federation_fetch_endpoint.

13.2. GET {base}/subordinates

Returns a page of Subordinate Documents. Default filter is status=active. Servers SHOULD omit jwks from list items unless the client passes detail=full.

13.3. POST {base}/subordinates

Creates a subordinate. entity_id is REQUIRED. Response 201. If a non-revoked subordinate with the same entity_id exists, the server MUST return 409 with problem type already_exists. Live verification (Section 9.8) applies. To register a subject that is not yet online, set status to pending.

13.4. GET, PUT, PATCH, DELETE {base}/subordinates/{entity_id}

Read, replace, merge-patch, or revoke the Subordinate Document. PATCH is the compact replacement for the per-claim URLs used in [Sphereon.Admin] and [GEANT.Admin]. Replace and merge-patch follow Section 9.8.

13.5. PUT {base}/subordinates/{entity_id}/status

Sets status without a full document write. Body: { "status": "suspended" }. The server MUST enforce Section 9.3. A transition to active MUST live-verify (Section 9.8).

13.6. GET {base}/subordinates/{entity_id}/statement

Returns the currently published Subordinate Statement JWT. This MUST be byte-for-byte the document the node's federation_fetch_endpoint returns for that subject when status is active. Otherwise 404 with problem type not_published.

14. Trust Marks

The Trust Marks resource is implemented by Trust Mark Issuers. Other nodes MUST return 404 with problem type unsupported_resource for every path under {base}/trust-marks.

This resource manages Trust Marks this node issues to subjects. Recognition claims (trust_mark_issuers, trust_mark_owners) and Trust Marks this node holds about itself (trust_marks) are Configuration Document members (Section 12).

14.1. Issuance Document

{
  "trust_mark_type": "https://ta.example.org/marks/research",
  "lifetime": 31536000,
  "logo_uri": "https://ta.example.org/marks/research.png",
  "ref": "https://ta.example.org/marks/research/policy"
}

trust_mark_type MUST be a collision-resistant identifier as specified in [OIDF.Federation], Section 7.1. logo_uri, ref, and delegation (when present) are copied into issued Trust Marks.

14.2. Subject Grant Document

{
  "entity_id": "https://op.example.org",
  "trust_mark_type": "https://ta.example.org/marks/research",
  "status": "active",
  "iat": 1756458000,
  "exp": 1787994000
}

When status is active, the node MUST issue a Trust Mark JWT whose claims follow Section 7.1 of [OIDF.Federation], typed trust-mark+jwt, and signed with a Federation Entity Key. When status is pending, suspended, or revoked, federation_trust_mark_status_endpoint MUST report the mark as inactive.

14.3. Collection and Item Operations

GET/POST {base}/trust-marks lists and creates Issuance Documents. GET/PUT/DELETE {base}/trust-marks/{type} reads, replaces, or revokes a type (revoking a type revokes every grant under it).

GET {base}/trust-marks/{type}/subjects lists grants. PUT .../subjects/{entity_id} creates or replaces a grant. DELETE revokes it. PUT .../status sets grant status. GET .../token returns the issued JWT with Content-Type: application/trust-mark+jwt when the grant is active.

Live verification (Section 9.8) applies to grant create, replace, and a status transition to active. To grant a mark to a subject that is not yet online, set status to pending.

15. Errors

Error responses MUST use HTTP status codes consistently with [RFC9110] and a [RFC9457] body:

{
  "type":
    "urn:ietf:params:oidfed:admin:problem#invalid_federation_claim",
  "title": "Invalid federation claim",
  "status": 400,
  "detail": "authority_hints must not be empty on a leaf node",
  "pointer": "/authority_hints"
}

pointer is an OPTIONAL JSON Pointer to the offending member.

Table 2: Problem tokens
Token Status Meaning
invalid_request 400 Malformed JSON or missing required member
invalid_federation_claim 400 Claim violates [OIDF.Federation]
unsupported_media_type 415 Wrong Content-Type
unauthorized 401 Missing or invalid authentication
forbidden 403 Authenticated but not permitted
not_found 404 Unknown resource or identifier
unsupported_resource 404 Resource not implemented for this node role
not_published 404 Configured but not currently published
already_exists 409 Identifier already in use
last_signing_key 409 Would remove the last usable signing key
not_initialized 409 Entity Identifier or signing key not yet set
conflict 409 Other conflicting state
precondition_failed 412 If-Match did not match
subject_mismatch 422 Live verification failed or subject unreachable
internal 500 Unspecified server failure

The type URI is formed by appending # and the token to urn:ietf:params:oidfed:admin:problem (Section 20).

16. Relationship to OpenID Federation 1.1

This section is normative regarding consistency and informative regarding existing products. OpenID Federation 1.1 [OIDF.Federation] is the protocol-independent split of OpenID Federation 1.0. It introduces no new federation mechanisms. OpenID Connect and OAuth metadata types used in examples (openid_provider, openid_relying_party) are defined in [OIDF.Connect].

Table 3: Admin resources and protocol artifacts
Admin resource Protocol artifact OIDFed section
Configuration Entity Configuration JWT 3, 9
Keys jwks; historical keys endpoint 3.1.1, 8.7, 11
Subordinate Subordinate Statement JWT from fetch 3, 8.1
Subordinate list federation_list_endpoint 8.2
Trust Mark grant Trust Mark JWT; status and list endpoints 7, 8.4–8.6
trust_mark_issuers Claim on Trust Anchor Entity Configuration 3.1.2, 7
metadata_policy Claim on Subordinate Statement 6.1
constraints Claim on Subordinate Statement 6.2

A node that implements this API MUST still implement the Protocol Plane required by its roles. Implementing this API does not satisfy any Protocol Plane requirement.

[Sphereon.Admin], [GEANT.Admin], and the OpenAPI contract shipped with [Gateway.Admin] expose a large set of nested resources that map onto the documents in this specification: entity-configuration metadata, authority hints, and published JWKS collapse to Section 12 plus Section 11; per-subordinate metadata, policy, constraints, and JWKS collapse to Section 13; trust-mark types, issuance specs, and subjects collapse to Section 14. Control-plane products such as [SURF.OIDFed] and [Gateway.Admin] sit above this API.

17. Deployment Considerations

The Administration API and the Protocol Plane MAY share an origin or MAY use distinct origins. Distinct origins are RECOMMENDED so that operator credentials never appear on the host that federation participants contact.

When origins differ, the Entity Identifier remains the Protocol Plane identifier. The Administration API base URL is local configuration. It MUST NOT be published in Entity Configuration metadata.

A control plane that manages several nodes MUST address each Administration Server separately. This document does not define a multi-node collection resource.

Servers SHOULD emit structured audit records for every mutating request, as specified in Section 18.10. This document does not define an Administration API resource for querying or managing those records.

18. Security Considerations

The Administration API can change the trust fabric of a federation. Compromise of Administration API credentials is equivalent to compromise of the node's Federation Entity Keys for the purpose of issuing statements the rest of the federation will accept.

18.1. Authentication and Authorization

Unauthenticated access MUST NOT be permitted. Bearer tokens MUST be sender-constrained or short-lived. Deployments SHOULD use mutual TLS or demonstration of proof-of-possession for operator credentials that can rotate keys or create subordinates. Separating "read configuration", "manage subordinates", "issue Trust Marks", and "rotate keys" is RECOMMENDED.

18.2. Cross-Origin and Browser Clients

If a browser-based operator interface is used, the Administration Server is a confidential backend-for-frontend concern. Browser clients MUST NOT be given long-lived node-admin credentials. Servers that offer CORS for a first-party UI MUST enumerate explicit origins and MUST NOT use *.

18.3. Replay and Session Theft

Bearer tokens that are not sender-constrained can be replayed until they expire. Servers MUST reject expired credentials. Clients SHOULD send If-Match on writes (Section 9); a replayed PUT or PATCH whose If-Match no longer matches MUST fail with 412.

If a deployment authenticates operators with cookies or other automatically attached credentials, it MUST implement cross-site request forgery defenses (for example a synchronized token or a custom request header that is not sent cross-origin). This document specifies Bearer tokens. Cookie sessions are not required and are NOT RECOMMENDED for the Administration API.

18.4. Injection into the Protocol Plane

Every written claim is copied into a signed JWT that third parties will cache and apply as policy. Servers MUST treat Admin Document fields as untrusted input: reject unexpected types, reject null inside metadata objects ([OIDF.Federation], Section 5), enforce URI syntax for Entity Identifiers and endpoints, and enforce https for federation endpoint URLs.

18.5. Entity Identifier Spoofing

A write that sets entity_id on a Subordinate Document or a Trust Mark grant is an assertion that the identified Entity is that subject. An Immediate Superior that publishes a Subordinate Statement binds the subject's Entity Identifier to the jwks in that document. Live verification (Section 9.8) MUST succeed before that binding is published. verify=false MUST NOT result in an active object. pending stores the document without publishing it.

A successful live check only shows that the subject currently publishes matching jwks and authority_hints, or that a Trust Chain can be built. It is not a proof of organizational control. naming_constraints and allowed_entity_types MUST still be applied when present.

18.6. Key Management

Private keys MUST NOT be exported through this API. Key rollover MUST keep the retiring public key published long enough for relying parties to refresh Entity Configurations ([OIDF.Federation], Section 11.2). Deleting the last signing key is rejected because it would freeze the Protocol Plane.

18.7. Server-Side Request Forgery

Live verification fetches a subject's Entity Configuration. Servers MUST apply SSRF controls: allow only https, deny private and link-local addresses unless explicitly configured, cap redirect hops, and cap response size.

18.8. Availability

Servers SHOULD rate-limit mutating requests, verify fetches, and expensive reads (detail=full and unfiltered lists). A client that can create subordinates or Trust Marks can otherwise exhaust storage and signing capacity. Unbounded list responses and repeated verify against slow or large Entity Configurations are denial-of-service vectors even for authenticated readers. Pagination (Section 9) is not optional for large collections if the server cannot bound the result set.

18.9. Residual Trust After Revoke

OpenID Federation 1.1 does not define a revocation protocol ([OIDF.Federation], Section 11.4). Setting status to suspended or revoked, or deleting a subordinate or Trust Mark grant, only stops this node from publishing the corresponding artifact. Relying parties continue to accept cached Entity Statements and Trust Marks until those artifacts expire or the relying party refreshes the Trust Chain. Operators MUST choose lifetime values that match how quickly the federation needs a withdrawal to take effect. DELETE is not instant global revocation.

18.10. Audit and Non-Repudiation

Administration actions SHOULD be attributable to an operator identity distinct from the node's Federation Entity Identifier. Audit logs are the primary record of who changed the trust fabric; Entity Statement iat values alone are not sufficient.

This document does not define an audit-log resource. Query, retention, and export to a SIEM or other archive are deployment concerns, typically implemented by a control plane rather than by the node.

A server SHOULD record at least the following for every mutating request:

  • time of the request (seconds since the epoch, or an equivalent unambiguous timestamp);
  • authenticated actor;
  • operation name from Appendix "Operation Catalog" (for example subordinates.replace);
  • target identifier (entity_id, trust_mark_type, or kid, as applicable);
  • previous etag or a hash of the previous Admin Document;
  • outcome (HTTP status, and problem token on failure).

Privileged read operations MAY be recorded. Servers MUST NOT write private key material or access tokens into the audit trail. Request and response bodies MAY be stored in redacted form.

The Administration API MUST NOT provide a means to delete or rewrite audit records. Retention period and archival policy are local matters.

If a control plane proxies this API, the node still SHOULD emit its own records. When it does not, the operator MUST designate exactly one authoritative trail so that a change cannot occur without a durable attribution.

19. Privacy Considerations

The Administration API handles identifiers and metadata that often relate to organizations and, in audit logs, to individual operators. This section follows the guidance of [RFC6973].

Entity Identifiers, organization_name, logo_uri, and similar metadata members are published on the Protocol Plane once written. Operators MUST treat Admin Document writes as publication. Contact addresses and other optional metadata SHOULD be limited to what the federation policy requires.

Trust Marks bind an accreditation statement to an Entity Identifier. Issuing or revoking a mark is visible to any party that can query the issuer's Trust Mark status endpoint.

Audit records contain operator identities distinct from the node's Entity Identifier (Section 18.10). Those records MUST be access-controlled independently of the Protocol Plane and SHOULD NOT be written to the same log streams that serve public federation endpoints. Retention of operator identifiers is a local matter. Servers MUST NOT copy operator identities into Entity Statements or Trust Marks.

Because the Administration API is confidential, responses MUST NOT be cached by shared caches. Distinct Administration and Protocol Plane origins (Section 17) reduce the risk that a browser or intermediary mixes the two.

20. IANA Considerations

This document makes no Well-Known URI registration. The Administration API is not discovered via /.well-known/openid-federation.

IANA is requested to register the following value in the "IETF URN Sub-namespace for Registered Protocol Parameter Identifiers" registry established by [RFC3553]:

Problem-type tokens in Section 15 are relative to urn:ietf:params:oidfed:admin:problem.

21. Normative References

[OIDF.Federation]
Hedberg, R., Jones, M.B., Ed., De Marco, G., Solberg, A.Å., Bradley, J., and V. Dzhuvinov, "OpenID Federation 1.1", OpenID Foundation Final, , <https://openid.net/specs/openid-federation-1_1.html>.
[RFC2119]
Bradner, S., "Key words for use in RFCs to Indicate Requirement Levels", BCP 14, RFC 2119, DOI 10.17487/RFC2119, , <https://www.rfc-editor.org/info/rfc2119>.
[RFC3553]
Mealling, M., Masinter, L., Hardie, T., and G. Klyne, "An IETF URN Sub-namespace for Registered Protocol Parameters", BCP 73, RFC 3553, DOI 10.17487/RFC3553, , <https://www.rfc-editor.org/info/rfc3553>.
[RFC3986]
Berners-Lee, T., Fielding, R., and L. Masinter, "Uniform Resource Identifier (URI): Generic Syntax", STD 66, RFC 3986, DOI 10.17487/RFC3986, , <https://www.rfc-editor.org/info/rfc3986>.
[RFC5789]
Dusseault, L. and J. Snell, "PATCH Method for HTTP", RFC 5789, DOI 10.17487/RFC5789, , <https://www.rfc-editor.org/info/rfc5789>.
[RFC6749]
Hardt, D., Ed., "The OAuth 2.0 Authorization Framework", RFC 6749, DOI 10.17487/RFC6749, , <https://www.rfc-editor.org/info/rfc6749>.
[RFC6750]
Jones, M. and D. Hardt, "The OAuth 2.0 Authorization Framework: Bearer Token Usage", RFC 6750, DOI 10.17487/RFC6750, , <https://www.rfc-editor.org/info/rfc6750>.
[RFC7396]
Hoffman, P. and J. Snell, "JSON Merge Patch", RFC 7396, DOI 10.17487/RFC7396, , <https://www.rfc-editor.org/info/rfc7396>.
[RFC7515]
Jones, M., Bradley, J., and N. Sakimura, "JSON Web Signature (JWS)", RFC 7515, DOI 10.17487/RFC7515, , <https://www.rfc-editor.org/info/rfc7515>.
[RFC7517]
Jones, M., "JSON Web Key (JWK)", RFC 7517, DOI 10.17487/RFC7517, , <https://www.rfc-editor.org/info/rfc7517>.
[RFC7519]
Jones, M., Bradley, J., and N. Sakimura, "JSON Web Token (JWT)", RFC 7519, DOI 10.17487/RFC7519, , <https://www.rfc-editor.org/info/rfc7519>.
[RFC7638]
Jones, M. and N. Sakimura, "JSON Web Key (JWK) Thumbprint", RFC 7638, DOI 10.17487/RFC7638, , <https://www.rfc-editor.org/info/rfc7638>.
[RFC8174]
Leiba, B., "Ambiguity of Uppercase vs Lowercase in RFC 2119 Key Words", BCP 14, RFC 8174, DOI 10.17487/RFC8174, , <https://www.rfc-editor.org/info/rfc8174>.
[RFC8259]
Bray, T., Ed., "The JavaScript Object Notation (JSON) Data Interchange Format", STD 90, RFC 8259, DOI 10.17487/RFC8259, , <https://www.rfc-editor.org/info/rfc8259>.
[RFC9110]
Fielding, R., Ed., Nottingham, M., Ed., and J. Reschke, Ed., "HTTP Semantics", STD 97, RFC 9110, DOI 10.17487/RFC9110, , <https://www.rfc-editor.org/info/rfc9110>.
[RFC9457]
Nottingham, M., Wilde, E., and S. Dalal, "Problem Details for HTTP APIs", RFC 9457, DOI 10.17487/RFC9457, , <https://www.rfc-editor.org/info/rfc9457>.
[RFC9525]
Saint-Andre, P. and R. Salz, "Service Identity in TLS", RFC 9525, DOI 10.17487/RFC9525, , <https://www.rfc-editor.org/info/rfc9525>.

22. Informative References

[Gateway.Admin]
Federation Gateway, "Federation Gateway", , <https://github.com/alexarlord-boop/federation-gateway>.
[GEANT.Admin]
GÉANT Trust and Identity Incubator, "Federation Admin API", , <https://gitlab.software.geant.org/TI_Incubator/federation-admin-api>.
[OIDF.Connect]
Hedberg, R., Jones, M.B., Ed., De Marco, G., Solberg, A.Å., Bradley, J., and V. Dzhuvinov, "OpenID Federation for OpenID Connect 1.1", OpenID Foundation Final, , <https://openid.net/specs/openid-federation-connect-1_1.html>.
[RFC6973]
Cooper, A., Tschofenig, H., Aboba, B., Peterson, J., Morris, J., Hansen, M., and R. Smith, "Privacy Considerations for Internet Protocols", RFC 6973, DOI 10.17487/RFC6973, , <https://www.rfc-editor.org/info/rfc6973>.
[RFC9421]
Backman, A., Ed., Richer, J., Ed., and M. Sporny, "HTTP Message Signatures", RFC 9421, DOI 10.17487/RFC9421, , <https://www.rfc-editor.org/info/rfc9421>.
[Sphereon.Admin]
Sphereon, "OpenID Federation Admin Server API", , <https://app.swaggerhub.com/apis/4Sure/OpenIDFederationAdminServer/0.20.0-d41>.
[SURF.OIDFed]
SURF, "SURF OpenID Federation", , <https://github.com/SURF-OpenID-Federation>.

Complete Message Examples

This appendix shows a Trust Anchor admitting an OpenID Provider and issuing a Trust Mark. Host names and keys are illustrative.

Register a subordinate

POST /admin/v1/subordinates HTTP/1.1
Host: ta.example.org
Authorization: Bearer 6f3c...
Content-Type: application/json

{
  "entity_id": "https://op.example.org",
  "jwks": {
    "keys": [{
      "kty": "EC", "crv": "P-256", "kid": "op-fed-1",
      "x": "f83OJ3D2xF1Bg8vub9tLe1gHMzV76e8Tus9uPHvRVEU",
      "y": "x_FEzRu9m36HLN_tue659LNpXW6pCyStikYjKIWI5a0"
    }]
  },
  "metadata": {
    "openid_provider": {
      "organization_name": "Example University"
    }
  },
  "constraints": {
    "max_path_length": 0,
    "allowed_entity_types": ["openid_provider"]
  }
}

The server live-verifies the subject's Entity Configuration before publishing (Section 9.8). If the subject were not yet online, the body would include "status": "pending" and the Protocol Plane would not change.

Tighten policy with a merge patch

PATCH /admin/v1/subordinates/https%3A%2F%2Fop.example.org HTTP/1.1
Host: ta.example.org
Authorization: Bearer 6f3c...
Content-Type: application/merge-patch+json
If-Match: "s1"

{
  "metadata_policy": {
    "openid_provider": {
      "id_token_signing_alg_values_supported": {
        "subset_of": ["ES256", "ES384"]
      }
    }
  }
}

Operation Catalog

The following operations are all of the protocol operations. Feature subsets are expressed only by omitting keys from capabilities. A Leaf implements the Node, Keys, and Configuration operations (ten). A Trust Anchor that also issues Trust Marks implements all twenty-eight. Paths in the catalog are relative to {base}.

Table 4: Complete operation catalog
Method Path Operation
GET / node.read
GET /keys keys.list
POST /keys keys.create
GET /keys/{kid} keys.read
DELETE /keys/{kid} keys.delete
POST /keys/{kid}/rotate keys.rotate
GET /configuration configuration.read
PUT /configuration configuration.replace
PATCH /configuration configuration.patch
GET /configuration/statement configuration.statement
GET /subordinates subordinates.list
POST /subordinates subordinates.create
GET /subordinates/{entity_id} subordinates.read
PUT /subordinates/{entity_id} subordinates.replace
PATCH /subordinates/{entity_id} subordinates.patch
DELETE /subordinates/{entity_id} subordinates.delete
PUT /subordinates/{entity_id}/
status
subordinates.status
GET /subordinates/{entity_id}/
statement
subordinates.statement
GET /trust-marks trust_marks.list
POST /trust-marks trust_marks.create
GET /trust-marks/{type} trust_marks.read
PUT /trust-marks/{type} trust_marks.replace
DELETE /trust-marks/{type} trust_marks.delete
GET /trust-marks/{type}/subjects trust_marks.subjects.list
PUT /trust-marks/{type}/subjects/
{entity_id}
trust_marks.grant
DELETE /trust-marks/{type}/subjects/
{entity_id}
trust_marks.revoke
PUT /trust-marks/{type}/subjects/
{entity_id}/status
trust_marks.status
GET /trust-marks/{type}/subjects/
{entity_id}/token
trust_marks.token

Acknowledgements

This document draws operational experience from the Sphereon OpenID Federation Admin Server, the GÉANT Trust and Identity Incubator Federation Admin API, the Federation Gateway project, and the SURF OpenID Federation control plane and node implementations. The data model is that of OpenID Federation 1.1; any elegance in this API comes from not inventing another one.

Author's Address

H.M. Kodden (editor)
SURF