# `Attesto.Federation.EntityStatement`
[🔗](https://github.com/XukuLLC/attesto/blob/v2.1.0/lib/attesto/federation/entity_statement.ex#L1)

Build and verify OpenID Federation 1.0 Entity Statements.

The module is transport-independent. An Entity Configuration produced by
`entity_configuration/3` is suitable for serving from the
`/.well-known/openid-federation` endpoint, but endpoint routing and HTTP are
deliberately left to the host application.

## Trust marks are NOT verified here

A `trust_marks` entry accepted by `build/3`/`verify/3` is only
*structurally* validated (non-empty `trust_mark_type` and `trust_mark` JWT
string) - the `trust_mark` JWT's signature, issuer, subject, and expiry are
never checked by this module. A host that wants to rely on a trust mark
(e.g. to gate participation) MUST separately verify it with
`Attesto.Federation.TrustMark.verify/3` against the Trust Mark Issuer's keys
before trusting it for anything.

# `signing_key`

```elixir
@type signing_key() :: module() | String.t()
```

# `verify_error`

```elixir
@type verify_error() ::
  :invalid_entity_statement
  | :invalid_typ
  | :invalid_alg
  | :unsupported_critical_header
  | :invalid_signature
  | :not_yet_valid
  | :expired
```

# `build`

```elixir
@spec build(signing_key(), map(), keyword()) :: String.t()
```

Build and sign an Entity Statement.

`claims` must provide string `iss` and `sub` values. Missing `iat`, `exp`,
and `jwks` values default to the selected signing key's current time,
one-hour lifetime, and public JWK respectively. A Subordinate Statement
normally supplies its subject's `jwks` explicitly.

Options include `:now`, `:iat`, `:exp`, `:lifetime` (with
`:lifetime_seconds` accepted as an alias), `:jwks`, and, for a PEM key,
`:alg`.

# `entity_configuration`

```elixir
@spec entity_configuration(signing_key(), String.t(), keyword()) :: String.t()
```

Build a self-issued Entity Configuration (`iss == sub`).

`:metadata`, `:authority_hints`, and `:trust_marks` are copied into the
configuration when present. The common signing and time options accepted by
`build/3` are also supported.

# `verify`

```elixir
@spec verify(String.t(), map() | [map()], keyword()) ::
  {:ok, map()} | {:error, verify_error()}
```

Verify an Entity Statement with trusted issuer keys.

Signature algorithm and `kid` selection are pinned to the protected header,
the `typ` header is mandatory, and all required claims and NumericDate
values are validated. `:accepted_algs` defaults to all asymmetric algorithms
supported by Attesto; `:now`, `:leeway`, `:issuer`, and `:subject` may also be
supplied.

# `verify_self_signed`

```elixir
@spec verify_self_signed(
  String.t(),
  keyword()
) :: {:ok, map()} | {:error, verify_error()}
```

Verify a self-issued Entity Configuration against its embedded public keys.

The embedded keys are untrusted until the compact JWS verifies; after that,
`iss == sub` and Entity Configuration-only claim placement are enforced.

---

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