---
title: "Trusting Issuers in Open-World OAuth"
date: "2026-07-05T14:00:00-07:00"
lastmod: "2026-07-05T14:00:00-07:00"
description: "Open-world OAuth needs a way to decide whether a previously-unknown issuer is trusted for a particular subject namespace. The Identity Assertion Trust Framework separates issuer authenticity from namespace authority, and the Domain-Authorized Issuer Trust Method gives domain owners a fail-closed way to publish that authority."
summary: "Self-service agent sign-up exposes a first-contact trust problem: a Resource Authorization Server can verify a perfectly valid JWT and still not know whether the issuer is allowed to assert identities for the user\u0026rsquo;s domain. That is two questions, not one. Federation proves the issuer is authentic, but not that the namespace owner authorized it, and static allowlists do not scale to onboarding unknown domains at runtime. The Identity Assertion Trust Framework lets a Resource AS publish the evidence it requires. The Domain-Authorized Issuer Trust Method lets a domain owner publish which issuers may assert identities in its namespace, fail-closed, the way mail and the web already pushed authority into DNS. Both compose with ID-JAG and the JWT-bearer grant without changing the grant surface."
slug: "trusting-issuers-in-open-world-oauth"
tags:
  - "OAuth"
  - "Authorization"
  - "Federation"
  - "ID-JAG"
  - "Open-World OAuth"
  - "Agentic Identity"
  - "Trust"
  - "DNS"
  - "Internet-Draft"
---


A downstream service can verify a perfectly valid JWT and still create the wrong account, bind the wrong tenant, or accept an issuer that has no authority to speak for the user's domain.

That is the trust bug open-world OAuth exposes. When an agent provider signs an identity assertion for a user and presents it to a downstream service the user has never connected to, the downstream service has to decide whether to accept the assertion. Signature validation is necessary. It is not the whole decision.

OAuth and JOSE can validate the JWT mechanics. OpenID Connect and OpenID Federation are designed to authenticate an issuer. What they do not standardize is the open-world trust decision at first contact: when a Resource Authorization Server has never seen this issuer before, how does it decide whether the issuer is trusted for this subject namespace?

The honest version of the question is: I can verify this JWT, but should I trust this issuer for this subject? That is not one question, it is two. Is the issuer authentic? And does the namespace owner authorize this issuer to assert identities in its namespace? Different questions, answered by different parties, with different evidence.

This post introduces two new drafts for that missing control plane. The [Identity Assertion Trust Framework](https://datatracker.ietf.org/doc/draft-mcguinness-oauth-id-assertion-framework/) defines the trust-evaluation model and the Trust Policy document the Resource AS publishes. The [Domain-Authorized Issuer Trust Method](https://datatracker.ietf.org/doc/draft-mcguinness-oauth-domain-authorized-issuer/), or DAI, defines a DNS-based mechanism the domain owner publishes to declare which issuers may assert identities in its namespace. Both compose with existing OAuth and OpenID Federation work. Neither changes the grant surface. Each is independently adoptable.

# Steel thread: self-service agent sign-up

Take the runtime sign-up case the [auth.md post](/notes/agent-provider-is-the-idp-standards-reading-of-workos-auth-md/) describes. Alice works at `acme.example`. She uses an agent run by `agentco.example` (the agent provider). She says to the agent: connect Notion. The agent has never registered with Notion before. Notion has never seen Alice or her agent provider before.

The Agent Verified path uses an ID-JAG to bootstrap the relationship. The agent provider's Authorization Server (`as.agentco.example`) mints an ID-JAG asserting Alice's identity, audienced at Notion's Resource Authorization Server (`as.notion.example`). The agent presents the ID-JAG via the RFC 7523 JWT-bearer grant. Notion's Resource AS runs validation, creates the account or binds the client, and issues a local access token for the API.

The validation step is the part everyone hand-waves. Notion's Resource AS has to decide: should I accept this assertion? Two questions resolve that decision.

1. Is `as.agentco.example` an authentic OAuth issuer, and is the JWT actually signed by it?
2. Does the namespace owner (the entity that controls `acme.example`) authorize `as.agentco.example` to assert identities for users at `acme.example`?

The first question is what federation is designed to handle, and OpenID Federation is the most developed implementation. It lets Notion verify that `as.agentco.example` is an authentic member of a known federation, signed into a trust chain by a trust anchor Notion recognizes.

The second question is not answered by federation. Federation membership proves ecosystem participation. It does not prove that a federation member is the right one for a given subject namespace. `as.agentco.example` is a perfectly legitimate AS for the agent provider's own users. The assertion in this flow is about a user at `acme.example`, a different namespace, where `as.agentco.example` may or may not be authorized to speak. Federation membership alone does not bind an issuer to a domain.

That distinction is the load-bearing claim of the entire design. Federation tells you the issuer is real. Namespace authority tells you the issuer is right for this user. Treating those as the same question is the bug. A federation member is still subject to authorization by the namespace owner for any namespace it asserts. Without that delegation, federation membership lets a legitimate AS impersonate users in domains it has no authority to speak for. The two drafts close that gap by separating the questions and assigning each one to the party that can answer it.

# Where the gap is today

[Open-World OAuth](/notes/oauth-for-open-world-ecosystems/) names this as the first-contact trust problem. OAuth's deployment model assumes that the AS, the RS, and the client knew each other before runtime. Self-service agent sign-up inverts that assumption. The agent provider reaches a previously-unknown Resource AS during the user's first attempt to connect. The trust topology has to extend across pairs of parties that have never paired.

The parties are easy to conflate. The validation result is only meaningful when each responsibility stays where it belongs:

| Party | Example | Responsibility |
| --- | --- | --- |
| Resource Authorization Server | `as.notion.example` | Publishes the Trust Policy, validates the assertion, and decides whether to issue a local token |
| Assertion Issuer | `as.agentco.example` | Signs the identity assertion presented by the agent |
| Subject Authority | `acme.example` | Controls the subject namespace and authorizes issuers for that namespace |
| Federation or trust anchor | A federation Notion trusts | Provides issuer-authentication evidence |
| Agent client | Alice's agent | Presents the assertion, but does not decide whether the issuer is trusted |

The existing tools each answer part of the question:

| Mechanism | What it proves | What it does not prove |
| --- | --- | --- |
| JWT validation | The assertion was signed by the key associated with `iss` | That the issuer is acceptable to this Resource AS |
| OAuth / OIDC metadata | Where the issuer publishes keys and endpoints | That the issuer may speak for `acme.example` |
| OpenID Federation | The issuer is an authentic member of a federation the Resource AS trusts | That the domain owner delegated namespace authority to this issuer |
| Static allowlist | The Resource AS operator pre-approved this issuer | Runtime self-service onboarding across unknown domains |
| Domain ownership alone | Who controls the namespace | Which issuers the namespace owner authorizes |
| DAI | The namespace owner authorized this issuer for this subject namespace | That the issuer is authentic or acceptable under the Resource AS policy |
| Trust Framework | How the Resource AS composes required evidence | The underlying trust evidence itself |

The [auth.md post](/notes/agent-provider-is-the-idp-standards-reading-of-workos-auth-md/) called out the missing piece: a symmetric trusted-issuer discovery mechanism. The Trust Framework and DAI are that mechanism. The Resource AS needs a way to declare what it trusts, in a published document rather than a config-file allowlist. The namespace owner needs a way to declare which issuers it authorizes, in a runtime-discoverable artifact rather than an offline federation registration. The Trust Framework defines the first. The Domain-Authorized Issuer Trust Method defines the second.

# The Identity Assertion Trust Framework

The [Trust Framework draft](https://datatracker.ietf.org/doc/draft-mcguinness-oauth-id-assertion-framework/) factors trust evaluation into two orthogonal categories.

- **`issuer_authentication`**. Is the JWT issuer an authentic ecosystem member? OpenID Federation answers this category by verifying a trust chain back to a trust anchor.
- **`subject_namespace_authorization`**. Has the Subject Authority for the subject's namespace actually authorized this issuer to assert identities in that namespace? The Subject Authority is the entity that controls the namespace, typically the owner of a registrable DNS domain for email-format subjects. Evidence comes from the Subject Authority, not from federation.

The combination rule is AND across categories, OR within. A Resource AS requires evidence for every category it declares. Within a category, one satisfied method is enough. Both categories must produce an Affirmative result. Indeterminate results (network failures, malformed responses) reject the assertion fail-closed.

For the two categories in the steel thread, that rule reads:

| Federation (`issuer_authentication`) | DAI (`subject_namespace_authorization`) | Result |
| --- | --- | --- |
| Affirmative | Affirmative | Accept, subject to Resource AS policy |
| Affirmative | Negative | Reject |
| Negative | Affirmative | Reject |
| Indeterminate on either | any state | Reject, fail-closed |

The Trust Framework defines two artifacts.

The first is the **Trust Policy document**, formally the Identity Assertion Issuer Trust Policy. A Resource AS publishes a JSON resource that names which grant profiles it supports, which subject identifier formats it accepts, and which Trust Methods it requires. A validator that holds an assertion fetches the Trust Policy, sees the required methods, gathers the evidence, and decides whether to accept.

The second is the **Trust Method**. A Trust Method names how a specific category gets satisfied. OpenID Federation membership is one Trust Method satisfying `issuer_authentication`. Domain-Authorized Issuer is one Trust Method satisfying `subject_namespace_authorization`. The framework defines the registry shape so additional methods can be added without rewriting the framework.

The Trust Framework is grant-agnostic. It applies to ID-JAG, the concrete binding the draft defines today. It applies to any other assertion-based grant where one AS issues an assertion that another AS validates, and it composes with OAuth Identity Chaining for cross-domain delivery.

# The Domain-Authorized Issuer Trust Method

The [DAI draft](https://datatracker.ietf.org/doc/draft-mcguinness-oauth-domain-authorized-issuer/) defines a concrete Trust Method that satisfies the `subject_namespace_authorization` category for email-domain subjects. The publication pattern mirrors CAA, MTA-STS, and DKIM. The domain owner publishes a policy at a well-known location, and validators look it up. What DAI adds on top of that pattern is the OAuth-specific binding: the policy names issuer URIs and the subject identifier formats they may assert, so a Resource AS can map an `iss` claim and an email-format `sub` claim to a deterministic authorization decision.

There are three publication channels.

- **DNS-inline form.** A TXT record at `_oauth-issuer-policy.{domain}` carries the authorized issuers directly. The syntax is `v=oauth-issuer-policy1; authority=acme.example; issuer=https://as.agentco.example`.
- **DNS pointer form.** A TXT record carries a `uri=` directive pointing at an HTTPS-hosted JSON document. The JSON form supports richer policy, including temporal bounds, tenant binding for multi-tenant IdPs, and subject identifier format restrictions.
- **HTTPS well-known.** When DNS returns no record, a validator falls back to `https://{domain}/.well-known/oauth-issuer-policy`.

The JSON policy document looks like this.

```json
{
  "subject_authority": "acme.example",
  "authorized_issuers": [
    {
      "issuer": "https://as.agentco.example",
      "subject_identifier_formats": ["email"],
      "valid_from": "2026-01-01T00:00:00Z",
      "valid_until": "2027-01-01T00:00:00Z"
    }
  ],
  "last_updated": "2026-05-01T00:00:00Z"
}
```

The lookup is deterministic and fail-closed, and it runs in a fixed precedence:

- **DNS-inline present.** Evaluate the inline policy carried in the TXT record.
- **DNS pointer present.** Fetch and evaluate the HTTPS JSON document it names.
- **DNS absent.** Fall back to the HTTPS well-known.
- **Timeout, malformed record, or DNSSEC failure.** Indeterminate, which rejects.
- **Confirmed absence across both DNS and the HTTPS well-known.** Negative, which also rejects.

So "both channels" means DNS and the HTTPS well-known must each come back empty before a lookup is Negative. Transitive authorization is bounded at depth one. The Subject Authority names issuers directly, and those issuers cannot themselves delegate further.

Determinism is not integrity, and the policy lives in DNS, so the draft is explicit about spoofing. The inline form has no signature of its own. Its authority binding is DNS control, the same basis CAA and DKIM rest on, hardened two ways. Behaviorally, a consumer discards any record whose `authority=` directive does not match the domain it queried, which closes off wildcard substitution. Cryptographically, Subject Authorities SHOULD sign `_oauth-issuer-policy.{domain}` with DNSSEC, a validating consumer treats a DNSSEC failure as Indeterminate rather than a clean Negative, and a consumer without DNSSEC SHOULD use a trustworthy resolver path. Many validators will not do DNSSEC validation, and for them DAI is only as strong as that resolver path and the DNS-control assumptions underneath it. Where stronger integrity is wanted, the pointer and HTTPS well-known forms put the authoritative policy behind the domain's own TLS. DNS stays authoritative when present, with the HTTPS well-known as the fallback on a Negative result. The posture is the one the design leans on by analogy: DNS control is the authority, and DNSSEC is the hardening.

DAI handles a deployment shape that matters in practice. Shared multi-tenant IdPs. A single issuer URL like `https://accounts.google.com` serves many tenants. The `tenant` field in an `authorized_issuers` entry binds authorization to a specific issuer-claimed tenant. Without that field, accepting an assertion from a shared issuer would silently authorize every tenant. With it, the domain owner can authorize a single tenant of a shared IdP without authorizing the rest.

An `acme.example` policy authorizing only its own tenant of a shared IdP names the tenant on the entry:

```json
{
  "issuer": "https://accounts.example-idp.com",
  "tenant": "acme",
  "subject_identifier_formats": ["email"]
}
```

The same issuer under `tenant: otherco` would not satisfy the lookup for an `acme.example` subject.

# Walking the validation

Back to the steel thread. Alice clicks Connect Notion. The agent presents the ID-JAG via JWT-bearer grant at `as.notion.example`. The validation runs as follows.

1. The assertion names `iss = https://as.agentco.example` and `sub` containing an `email` claim ending in `@acme.example`.
2. `as.notion.example` reads its own Trust Policy. The policy requires `issuer_authentication` and `subject_namespace_authorization`.
3. For `issuer_authentication`, the validator runs an OpenID Federation lookup to confirm `as.agentco.example` is an authentic federation member with a valid trust chain.
4. For `subject_namespace_authorization`, the validator extracts the subject authority from the assertion. The registrable domain of the email is `acme.example`. It looks up `_oauth-issuer-policy.acme.example` via DAI. The DNS record parses cleanly, the `authority=` directive matches the queried domain, the temporal bounds cover the current time, and the policy lists `https://as.agentco.example` as an authorized issuer for the email format.
5. Both categories return Affirmative, so the Resource AS accepts the assertion as an authentic, authorized identity claim. What it does next is a separate policy decision. Here Notion runs the JWT-bearer grant, provisions or binds Alice's account, and issues a local access token. Whether it also registers the agent as an OAuth client is its own onboarding policy, not something issuer trust decides.

If `acme.example` had not published a DAI policy, the lookup would be Indeterminate or Negative, and the Resource AS would reject the assertion. If `as.agentco.example` had not been federated, federation membership would fail. The AND-across-categories rule turns either gap into a deny. Sign-up proceeds only when both questions resolve Affirmative.

Neither the ID-JAG nor the JWT-bearer grant changes. The Trust Framework is exercised at the validation step inside `as.notion.example`. The Trust Policy is published by `as.notion.example`. Issuer metadata and federation evidence come from or about `as.agentco.example`. The DAI policy is published by `acme.example`. The wire shape from the agent's perspective is the same one the existing ID-JAG and JWT-bearer flow defines.

# Failure modes the drafts have to handle

The denial cases are where the design earns its keep. The important failure modes are:

- **Issuer is authentic but not authorized for the namespace.** Federation succeeds, DAI fails, and the assertion is rejected.
- **The Subject Authority authorizes an issuer that cannot be authenticated.** DAI succeeds, issuer authentication fails, and the assertion is rejected.
- **DAI lookup is unavailable or malformed.** The result is Indeterminate, which rejects fail-closed.
- **A shared issuer is authorized without tenant binding.** The validator must avoid treating one tenant's authorization as authorization for every tenant behind the same issuer URL.
- **An authorized issuer tries to delegate onward.** DAI does not allow unbounded transitive delegation. The Subject Authority names authorized issuers directly.
- **The Resource AS policy and domain policy disagree.** The Resource AS policy wins for acceptance because it is the party issuing the local token. Domain authorization is necessary evidence, not a command to accept.

# Relating back to the series

[Open-World OAuth Part 1](/notes/oauth-for-open-world-ecosystems/) named five substrate gaps: discovery, resource binding, sender constraints, metadata integrity, and first-contact trust. PRM, CIMD, DPoP, and signed metadata address the first four. First-contact trust is what these two drafts address. They are the symmetric counterpart to PRM. PRM lets a client discover the AS that protects a resource. DAI lets the Resource AS validate that an issuer is the right one for a subject's domain. The Trust Framework defines how the Resource AS expresses what it requires.

[The Agent Provider Is the IdP](/notes/agent-provider-is-the-idp-standards-reading-of-workos-auth-md/) argued that the auth.md design was right to adopt ID-JAG. The Agent Verified path it describes composes cleanly with both drafts. The agent provider is the IdP AS. The downstream service runs the validation. The namespace owner publishes the authority. Self-service agent sign-up becomes open-world-safe without requiring the agent provider and the downstream service to pre-pair.

# Incremental adoption

The two drafts are independent, though the value is asymmetric. A Trust Policy on its own improves how a Resource AS declares what it requires. DAI on its own publishes namespace authority, but it does nothing until validators consume it. Together they close the open-world gap, and a deployment does not have to start with both.

The adoption path that makes sense in practice looks like this.

1. **Publish a Trust Policy document.** A Resource AS that already runs a static allowlist can publish it in Trust Policy form. The change is a JSON document at a well-known location, no wire-level changes. The benefit is that validators and operators can read what is required rather than discovering it through trial.
2. **Adopt OpenID Federation for `issuer_authentication`.** If the Resource AS is already a federation member or can join one, the `issuer_authentication` category lights up with one Trust Method already defined. The Trust Policy now declares federation as the required method.
3. **Publish DAI for one domain.** The domain owner (which may be an IT admin at the enterprise, or the operator of an IdP service) publishes a DNS record naming the authorized issuer. The investment is one TXT record. The benefit is that any Resource AS adopting DAI as a Trust Method can validate assertions for that domain at runtime without manual configuration.
4. **Validators adopt DAI as a Trust Method.** Resource ASes that want to accept assertions from previously-unknown IdPs add the DAI Trust Method to their Trust Policy. The first time they receive an assertion from a domain they have not seen, they look up the DAI policy and decide. The static allowlist becomes a backup rather than the primary gate.
5. **Retire the static allowlist.** Once DAI is deployed across the domains the Resource AS cares about, the allowlist is redundant. The Trust Policy is the declaration. DAI is the discovery. Federation is the authenticity check.

A deployment can stop at any step. A deployment that only publishes a Trust Policy gets clearer policy declaration. A deployment that adopts federation gets standardized authenticity evaluation. A deployment that publishes DAI gets namespace-authority delegation without coordinating with every downstream Resource AS by hand.

# Value proposition

The drafts pay off before full deployment, because each piece is useful on its own.

- **For Resource ASes.** Declare what you require in a Trust Policy. Stop maintaining static allowlists. Accept assertions from previously-unknown issuers when the assertion satisfies your declared requirements. The fail-closed semantics keep the system safe under partial information.
- **For agent providers and other IdP ASes.** Operate in an open ecosystem. Have your assertions accepted by Resource ASes you have never paired with, as long as the namespace owner authorizes you and you participate in a recognized federation. Move re-keying, rotation, and migration into runtime concerns rather than coordinated-with-every-RP changes.
- **For domain owners.** Control which issuers can assert identities for users at your domain. Authorize the agent providers your users are allowed to use, and no others. Re-delegate without rewriting allowlists at every Resource AS. Multi-tenant SaaS IdPs can be authorized for one tenant without authorizing the rest, addressing a long-standing gap that shared multi-tenant JWKS endpoints make painful today.
- **For the agent ecosystem.** Self-service agent sign-up actually works across trust domains without pre-pairing. The Agent Verified path described in [The Agent Provider Is the IdP](/notes/agent-provider-is-the-idp-standards-reading-of-workos-auth-md/) becomes open-world-safe. A user can connect a new tool through their agent, and the downstream service can validate the assertion without prior knowledge of the agent provider.
- **For the standards layer.** Federation and namespace authority are factored apart. Each side of the trust question lives where it belongs. Federation operators do not have to mediate every domain-authority delegation. Domain owners do not have to join every federation a Resource AS recognizes.

The deeper value is that open-world OAuth becomes a question of published policy rather than a question of pre-shared state. That is the move every successful internet protocol eventually makes. Mail did it with SPF, DKIM, and DMARC, the web with CAA, HSTS, and MTA-STS. Those mechanisms differ in what they secure, but they share one pattern, the domain owner publishing authority where anyone can find it. OAuth is making the same move for identity-assertion authority now.

# What the drafts do not solve

The drafts answer a specific question. Can a Resource AS accept an identity assertion from a previously-unknown issuer? They do not solve identity assurance, the agent's authority to act on the user's behalf, the agent's own client authentication, or downstream policy decisions about what the user is actually allowed to do at the resource. Those are governed by client authentication and instance attestation, runtime FGA, and the resource's own policy layer. Trust Framework and DAI sit at the bootstrapping layer. They make the first identity claim trustworthy. Everything above that layer still has to do its job.

# Where the drafts go next

Both are now individual Internet-Drafts submitted to the IETF, and the natural path is OAuth Working Group adoption. The Trust Framework is the broader of the two and has the larger surface to socialize. DAI is narrower and proves out the namespace-authority half of the framework with a concrete, deployable mechanism. The two can advance together, or DAI can move ahead of the framework as an independent Trust Method specification. Reviews, implementation experiments, and deployment feedback from agent providers, IdP operators, domain owners, and Resource ASes are the next thing the drafts need.

Open-world OAuth cannot be built on issuer authenticity alone. It needs namespace authority as a first-class validation input. These drafts make that authority publishable, discoverable, and fail-closed.

