# `Arc.Authentication.MicrosoftIdentityPlatform`
[🔗](https://github.com/Cratis/Arc.Elixir/blob/main/lib/arc/authentication.ex#L73)

Authenticates from the Microsoft identity platform headers an ingress supplies:
`x-ms-client-principal` (a base64 client principal), `x-ms-client-principal-id` and
`x-ms-client-principal-name`. These are what Azure App Service, Container Apps, Cratis AuthProxy
and the Lens browser extension send.

The headers are **not signed** by default. The handler ignores them, and the request stays
anonymous, unless the application sets `trust_forwarded_identity_headers: true`. Enable that only
when every request reaches the application through an ingress that authenticates callers, strips
caller-supplied identity headers and writes trusted replacements, and when nothing can reach the
application directly. The setting applies to every route.

    config :my_app, MyApp.Arc,
      authentication: [Arc.Authentication.MicrosoftIdentityPlatform],
      trust_forwarded_identity_headers: true

To have the ingress attest the headers, enable [signed forwarded identity](`Arc.Identity.SignedForwarding`):
with it there is no unsigned fallback. To let a support person or an agent act as a user, enable
[on-behalf forwarding](`Arc.Identity.OnBehalfOf`).

## The principal

Without signing, all three headers must be present, otherwise the request is left to the next
handler. The id is the decoded `x-ms-client-principal-id` (RFC 8187 `UTF-8''` form
percent-decoded). The name is the principal's `userDetails`, falling back to
`x-ms-client-principal-name`. Roles are `userRoles` plus claims of the role claim type
`http://schemas.microsoft.com/ws/2008/06/identity/claims/role`; `sub` and the name identifier come
from the id header, replacing any in the payload. The identity provider the ingress authenticated with is kept as the claim
`urn:cratis:arc:identity:provider`. A payload that is not a valid client principal fails the request with 401.

---

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