# `Attesto.AuthorizationCode.Grant`
[🔗](https://github.com/XukuLLC/attesto/blob/v2.0.1/lib/attesto/authorization_code/grant.ex#L1)

The validated context a successfully redeemed authorization code yields.

`Attesto.AuthorizationCode.redeem/4` returns this struct once the code's
expiry, redirect URI, PKCE verifier, and DPoP binding have all checked
out. The host reads it to mint the access token (and, if it issues one,
the refresh token): `subject` and `scope` become the token's `sub` and
`scope`, `dpop_jkt` (when present) becomes the access token's `cnf.jkt`,
and `claims` carries the lossless, string-keyed I-JSON host context that rode
along from the authorization request. Persisted claim numbers are limited to
exact-range integers; floats and unsupported VM terms are rejected.

## `family_id`

When the authorization request supplied a `:family_id` to
`Attesto.AuthorizationCode.issue/3`, it rides through to this struct as
provenance metadata. Public `Attesto.RefreshToken.issue/3` rejects that
value and creates a fresh family. After the host successfully issues that
refresh token, it should use
`Attesto.AuthorizationCode.issue_refresh_and_finalize/6`, which captures the
returned family ID so code-reuse detection can revoke the actual descendants
(OAuth 2.0 Security BCP §4.13). That helper also requires the issued refresh
context to retain this grant's subject and client and to narrow, never widen,
its scope/resource authorization. `AuthorizationCode.finalize/3` is for
no-refresh flows and records a nil family in its replay marker. `nil` when no
provenance ID was supplied.

Under RFC 9449 §5, public-client refresh tokens must be DPoP-bound while
confidential-client refresh tokens must not be DPoP-bound. The host performs
that client classification because core cannot know it. For a DPoP-bound
grant, the composition helper accepts a refresh context with either a nil
`dpop_jkt` (confidential refresh) or this grant's exact JKT (public refresh),
and rejects a different JKT.

# `t`

```elixir
@type t() :: %Attesto.AuthorizationCode.Grant{
  claims: map(),
  client_id: String.t(),
  dpop_jkt: String.t() | nil,
  family_id: String.t() | nil,
  redirect_uri: String.t(),
  resource: [String.t()],
  scope: [String.t()],
  subject: String.t()
}
```

---

*Consult [api-reference.md](api-reference.md) for complete listing*
