Internet-Draft FedAuthz for Agents September 2026
Gamb & Maler Expires 15 March 2027 [Page]
Workgroup:
Network Working Group
Internet-Draft:
draft-gamb-uma4agents-fedauthz-00
Published:
Intended Status:
Standards Track
Expires:
Authors:
N. Gamb
MindGarden LLC
E. Maler
Venn Factory

Federated Authorization for Autonomous Agents

Abstract

This document extends Federated Authorization for User-Managed Access (UMA) 2.0 in three places where the agent era exposes an assumption.

Resource registration becomes declarative: the resource server publishes its structure in protected resource metadata and serves its owner-bound instances only to the owner's authorization server, which pulls rather than being pushed to. A resource server establishes its relationship with an owner's authorization server by signing as the origin it serves, rather than by a credential somebody had to provision at both ends. And the protection API's introspection response says why a token is inactive, so an enforcement point can tell a refusal that further negotiation might change from one it cannot.

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 15 March 2027.

Table of Contents

1. Introduction

[UMAFedAuthz] separates the resource server from the authorization server so that the owner's policy can live with a party the resource server does not control. It then assumes the two are already acquainted: the resource server holds a protection API access token (PAT), pushes descriptions of the owner's resources under it, and asks it for permission tickets.

Each of those assumptions holds when one operator runs both sides and stops holding when the authorization server is the owner's. Nobody can provision a secret at both ends when the two ends belong to different people. Pushing owner-bound resource descriptions requires the resource server to know, per owner, which authorization server to push to. And a resource server that has registered a resource with one owner's authority has published, to that authority, which resources that named person owns — which the resource server was in a position to know and the metadata document it publishes to the world must not be.

This document keeps the direction [UMAFedAuthz] chose — the authorization server is the owner's, and the resource server is its client — and specifies the three things it left to deployment.

1.1. Relationship to the Set

This document extends [UMAFedAuthz] and is REQUIRED to implement alongside [U4ACore]. Its identifying URI is https://u4a.ai/spec/fedauthz/1.0.

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.

2. Discovery in Two Layers

Discovery is split by who may ask.

2.1. The Public Layer

A resource server MUST publish protected resource metadata [RFC9728] for each resource it serves. That document describes the structure of the resource: what operations it offers and with what scopes. It MUST NOT name which owners have instances behind it.

This document adds two members to the metadata:

tool_surfaces:

OPTIONAL. An array of objects, each with a tool member naming an operation and a resource_scopes member listing the scopes that operation requires. Structural only.

owner_resources_endpoint:

REQUIRED. The URL of the protected listing of Section 2.2.

The document MUST carry signed_metadata as [RFC9728] Section 2.1, signed by a key published at the resource's own jwks_uri, so that a relayed copy stays attributable to the resource.

A resource server MAY publish the same structural facts in more than one encoding — for example the metadata of [I-D.hardt-aauth-protocol] alongside [RFC9728] — from one registry. The instance layer beneath them, and the permission ticket, do not change with the encoding.

2.2. The Protected Layer

A resource server MUST serve, at owner_resources_endpoint, the owner-bound resource instances it holds for one owner — their identifiers, names, and scopes — and MUST serve them only to a request signed with [RFC9421] by the authorization server that owner has named, verified against that authorization server's published keys.

The signature profile is that of [U4ACore] Section 6.1, with @authority taken from the resource server's configuration.

This is the privacy split. The public document says what the resource is; whose things sit behind it is served only to the party the owner's own consent already connected. Publishing the second at an unauthenticated URI is a disclosure that push registration, for all its other costs, never made.

3. Declarative Registration

An authorization server implementing this document MUST be able to learn what a resource server protects by fetching, and MUST NOT require the resource server to push resource descriptions. The classic resource registration endpoint of [UMAFedAuthz] Section 3 remains conformant and MAY be offered alongside.

To register a resource server's resources for an owner, the authorization server:

  1. fetches the resource server's protected resource metadata;

  2. verifies signed_metadata against the keys at the document's jwks_uri, and verifies that the signed claims name this resource as iss;

  3. sends a signed request to owner_resources_endpoint;

  4. materializes its registry for that owner from the response, and removes any registration from that source for that owner that the response no longer carries.

One fetch replaces N registration calls, and there is one registry with one writer.

3.1. Staleness

The registry the authorization server holds may lag what the resource server serves. When a permission request names a resource identifier the authorization server does not hold, it MUST attempt a fresh pull before answering invalid_resource_id.

This is the mirror of what [UMAFedAuthz] asked of the resource server — noticing invalid_resource_id after an authorization server restart and re-pushing — placed with the party that can act on it without a round trip.

3.2. Liveness

The pull and its verification form a call cycle: the authorization server fetches from the resource server, and the resource server authenticates that fetch by dereferencing the authorization server's published keys. An authorization server MUST NOT condition its own readiness on the pull having completed, and a resource server verifying a signed request MUST either tolerate a live back-call to the authorization server or verify against keys it already holds.

Gating readiness on "my registry is populated" deadlocks: the authorization server will not serve its keys until it has pulled, and the resource server will not serve the pull until it has the keys. The general form is that in a profile where two parties authenticate each other by dereference, neither party's liveness may be conditioned on the exchange completing.

4. Establishment

[UMAFedAuthz] Section 1.4 requires that the PAT be issued with the resource owner's authorization, and says nothing about how the resource server comes to be a client of the authorization server at all. Where one operator runs both sides, a provisioned client credential models that gap adequately. Where the authorization server is the owner's, nobody is in a position to configure both ends.

4.1. Registration by Origin

A resource server MAY introduce itself to an owner's authorization server by sending a request naming the owner and the resource it serves, signed with [RFC9421] using a key published at the origin of that resource.

The request MUST carry a Content-Digest [RFC9530] covered by the signature.

POST /rs/register HTTP/1.1
Host: alice-as.example
Content-Type: application/json
Content-Digest: sha-256=:X48E9qOokqqrvdts8nOJRJN3OWDU=:
Signature-Input: sig1=("@method" "@authority" "@path"
  "authorization" "content-digest");created=1789430000;
  keyid="rs-1";alg="ed25519"
Signature: sig1=:bbN8ISG...:

{
  "owner": "alice",
  "resource_uri": "https://rs.example/mcp/alice",
  "name": "Meridian Vault"
}
Figure 1: A resource server registering by origin signature. Line breaks are for display only.

The authorization server MUST verify the signature by:

  1. fetching the protected resource metadata for resource_uri from that resource's own origin;

  2. refusing unless the document's resource equals resource_uri, its jwks_uri is same-origin with resource_uri, and its authorization_servers names this authorization server;

  3. fetching the keys at jwks_uri and verifying the signature against them.

A resource server that cannot be reached, or whose document fails any of the three checks, MUST be refused. This is a deliberate departure from how an authorization server treats an operator's key directory, where an unreachable document leaves an agent's claim where it was. There, the document attests a claim already made by other means. Here, the document is the credential, and a credential that cannot be fetched has not been presented. A profile that reuses the attestation language here has specified an authentication that fails open.

4.2. The Answer Is the Owner's

A verified signature settles who is asking and nothing else. On success the authorization server MUST respond 202 Accepted with a body carrying status of pending and error of authorization_pending, MUST record the resource server in the owner's registry as pending, and MUST issue no PAT until the owner has approved it.

{
  "client_id": "https://rs.example",
  "status": "pending",
  "error": "authorization_pending",
  "error_description": "the owner has been asked"
}

The client_id of a resource server registered this way is its origin.

Registration reaches an owner; it MUST NOT create one. The signature proves control of an origin and says nothing about whether the owner named beside it exists. An authorization server that seeds an owner on demand has turned an unauthenticated endpoint into unbounded state.

4.3. Obtaining the PAT

Once the owner has approved, the resource server obtains a PAT with the client_credentials grant [RFC6749] and scope of uma_protection, as [UMAFedAuthz] Section 1.5, authenticating in the same way it registered: by an [RFC9421] signature over the token request, verified against keys at the origin it registered as. Which authentication applies — a provisioned secret or an origin signature — is a property of the stored registration, so that a resource server registered by signature cannot later fall back to guessing a secret.

While the owner has not answered, the token endpoint MUST respond 403 with error of authorization_pending. After the owner has revoked the resource server, it MUST respond 403 with error of access_denied.

4.4. Withdrawal

The owner MUST be able to revoke a resource server, and on revocation the authorization server MUST stop honouring that resource server's PAT on every protection API call, from every replica, at once.

A resource server that registers again after being revoked MUST land in the pending state, not the active one. A second request is not a reversal of the owner's first decision, and re-registration MUST NOT be a way to undo a withdrawal.

5. Introspection Reasons

An authorization server MUST include, in an introspection response [RFC7662] whose active member is false, an error member. The following values are defined:

expired:

The token's lifetime has passed.

invalid_signature:

The token did not verify.

unknown_token:

The token was not issued by this authorization server, or its record is gone.

already_consumed:

A single-use token has been spent.

connection_revoked:

The owner has ended the standing relationship under which this token was issued. See [U4ACore] Section 9.

Of these, connection_revoked is terminal: an enforcement point receiving it MUST refuse without issuing a fresh challenge, because renegotiation cannot change an outcome the owner has settled. The others MAY be answered with a fresh challenge.

An extension MAY define further values. [U4AMultiParty] defines organization_revoked.

5.1. Non-Consuming by Default

Introspection MUST NOT consume a single-use token. Consumption is a separate operation, taken by the enforcement point as the last step of enforcement, as [U4ACore] Section 8.2. An authorization server MUST offer that operation at the URL it advertises as consume_endpoint in its metadata, MUST require the protection API access token on it as on introspection, and it MUST report to its caller whether that caller was the one that consumed the token.

The request carries the token as introspection does; the response is a JSON object with a consumed member. true means this caller spent the token; false means it was already spent, or was not a single-use token, and MUST be accompanied by an error member saying which.

6. Reporting Allowed Access

An enforcement point SHOULD report each call it allows to the authorization server, naming the negotiation it was made under and what was reached, so that the owner's record holds what was done alongside what was promised.

An enforcement point MUST NOT be told, and MUST NOT report, the identity handle of the requesting agent. The authorization server resolves it from the negotiation. The enforcement point is the resource server's component, and the owner's record of which agent did what is not the resource server's to hold.

7. Security Considerations

The considerations of [UMAFedAuthz] Section 7 apply.

7.1. An Endpoint That Dereferences Will Dereference What It Is Told

Section 4.1 carries no credential the authorization server issued; the signature checked against the origin's own published document is the credential. Any caller can therefore cause an outbound fetch to a host they name. An authorization server MUST bound the response size it will read, MUST NOT follow redirects, MUST require https, and SHOULD keep a short memory of resources that did not check out so that a flood of registrations is not a flood of fetches.

The bound this document deliberately does not require is an address blocklist. A resource server legitimately sits on a private range whenever it is deployed near its owner's authority, so refusing those would break the honest case and not the dishonest one. Naming the hosts an authorization server may reach is an egress policy and belongs to the deployment.

7.2. The Owner's Policy Is Not on the Protection API

The protection API is scoped to the PAT, and it carries no operation that returns the owner's policy. An implementation SHOULD be able to demonstrate that the enforcement point is refused the owner's policy and is allowed her published keys, on the same origin.

7.3. Revocation Reads the Store

Section 4.4 requires that a revoked PAT stop working on every replica at once, which means the resource server's status MUST be read on each protection API call rather than cached in process. A revocation that reached only the replica that served the request would leave the others honouring a credential the owner had just withdrawn.

8. Privacy Considerations

The considerations of [UMAFedAuthz] Section 8 apply.

The split in Section 2 exists because the alternative is a disclosure. A public document listing the resources a named person owns is readable by anyone who can guess its URL, and a resource server serving many owners has published a directory of them. The structural layer says nothing about any person; the instance layer is served only to the authority that person named, and that authority already knew.

9. IANA Considerations

9.1. OAuth Protected Resource Metadata Registration

IANA is asked to register the following in the "OAuth Protected Resource Metadata" registry established by [RFC9728].

Metadata Name:

tool_surfaces

Metadata Description:

Operations the resource offers, each with the scopes it requires

Change Controller:

IETF

Specification Document(s):

Section 2.1 of this document

Metadata Name:

owner_resources_endpoint

Metadata Description:

URL of the protected listing of owner-bound resource instances

Change Controller:

IETF

Specification Document(s):

Section 2.2 of this document

9.2. OAuth Authorization Server Metadata Registration

IANA is asked to register the following in the "OAuth Authorization Server Metadata" registry established by [RFC8414].

Metadata Name:

consume_endpoint

Metadata Description:

URL of the operation that spends a single-use requesting party token

Change Controller:

IETF

Specification Document(s):

Section 5.1 of this document

9.3. OAuth Token Introspection Response Registration

IANA is asked to register the following in the "OAuth Token Introspection Response" registry established by [RFC7662].

Name:

error

Description:

Why an inactive token is inactive; see Section 5 of this document

Change Controller:

IETF

Specification Document(s):

Section 5 of this document

10. References

10.1. Normative References

[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/rfc/rfc2119>.
[RFC6749]
Hardt, D., Ed., "The OAuth 2.0 Authorization Framework", RFC 6749, DOI 10.17487/RFC6749, , <https://www.rfc-editor.org/rfc/rfc6749>.
[RFC7662]
Richer, J., Ed., "OAuth 2.0 Token Introspection", RFC 7662, DOI 10.17487/RFC7662, , <https://www.rfc-editor.org/rfc/rfc7662>.
[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/rfc/rfc8174>.
[RFC8414]
Jones, M., Sakimura, N., and J. Bradley, "OAuth 2.0 Authorization Server Metadata", RFC 8414, DOI 10.17487/RFC8414, , <https://www.rfc-editor.org/rfc/rfc8414>.
[RFC9421]
Backman, A., Ed., Richer, J., Ed., and M. Sporny, "HTTP Message Signatures", RFC 9421, DOI 10.17487/RFC9421, , <https://www.rfc-editor.org/rfc/rfc9421>.
[RFC9530]
Polli, R. and L. Pardue, "Digest Fields", RFC 9530, DOI 10.17487/RFC9530, , <https://www.rfc-editor.org/rfc/rfc9530>.
[RFC9728]
Jones, M.B., Hunt, P., and A. Parecki, "OAuth 2.0 Protected Resource Metadata", RFC 9728, DOI 10.17487/RFC9728, , <https://www.rfc-editor.org/rfc/rfc9728>.
[U4ACore]
Gamb, N. and E. Maler, "User-Managed Access (UMA) 2.0 Profile for Autonomous Agents", Work in Progress, Internet-Draft, draft-gamb-uma4agents-core-00, , <https://u4a.ai/spec/draft-gamb-uma4agents-core-00.html>.
[UMAFedAuthz]
Maler, E., Machulak, M., and J. Richer, "Federated Authorization for User-Managed Access (UMA) 2.0", Kantara Recommendation, , <https://docs.kantarainitiative.org/uma/wg/rec-oauth-uma-federated-authz-2.0.html>.

10.2. Informative References

[I-D.hardt-aauth-protocol]
Hardt, D., "AAuth Protocol", Work in Progress, Internet-Draft, draft-hardt-aauth-protocol-02, , <https://datatracker.ietf.org/doc/html/draft-hardt-aauth-protocol-02>.
[RFC7942]
Sheffer, Y. and A. Farrel, "Improving Awareness of Running Code: The Implementation Status Section", BCP 205, RFC 7942, DOI 10.17487/RFC7942, , <https://www.rfc-editor.org/rfc/rfc7942>.
[U4ALAB]
Gamb, N. and E. Maler, "UMA for Agents: a reference implementation", , <https://github.com/nickgamb/uma4agents>.
[U4AMultiParty]
Gamb, N. and E. Maler, "Multi-Party Authorization for User-Managed Access (UMA) 2.0", Work in Progress, Internet-Draft, draft-gamb-uma4agents-multiparty-00, , <https://u4a.ai/spec/draft-gamb-uma4agents-multiparty-00.html>.

Appendix A. Implementation Status

This section records the status of known implementations in the sense of [RFC7942], and is to be removed before publication as an RFC.

The reference implementation [U4ALAB] implements this document in full. Both registration methods — declarative pull and the classic push endpoint of [UMAFedAuthz] — were built against an otherwise identical stack and measured before push was retired to a preserved branch. The deadlock of Section 3.2 and the fail-open reading that Section 4.1 warns against were both found by running it.

Acknowledgments

This document rests on [UMAFedAuthz], whose separation of resource server from authorization server is the arrangement everything here depends on. [RFC9728] supplied the public half of discovery, and the observation that a resource may name its authorization servers is what made the split in Section 2 possible.

Authors' Addresses

Nick Gamb
MindGarden LLC
Eve Maler
Venn Factory