Migrating to secure defaults
Some Arc defaults used to be convenient but unsafe on a deployed host. Arc now ships safe defaults instead. Read each section below and check whether your application relies on the old behavior. Each section ends with the single change that restores it.
Forwarded identity headers need an explicit opt-in
Section titled “Forwarded identity headers need an explicit opt-in”Who is affected: applications that authenticate users through the unsigned
x-ms-client-principal, x-ms-client-principal-id and x-ms-client-principal-name headers.
That is every application that calls builder.AddCratis(), or
builder.Services.AddMicrosoftIdentityPlatformIdentityAuthentication(), and runs behind Azure
App Service or Container Apps authentication (EasyAuth) or Cratis AuthProxy. On the Arc.Core
HttpListener host it is every application that relies on the built-in
MicrosoftIdentityPlatformAuthenticationHandler.
What changed: Arc used to trust these headers from any caller. Anyone who could reach the application directly could send them and act as any user. Arc now ignores them until the host opts in. Without the opt-in, these headers do not authenticate requests; endpoints that require an authenticated user return 401 unless another authentication scheme authenticates the caller.
How to tell: an ASP.NET Core host that calls
AddMicrosoftIdentityPlatformIdentityAuthentication() (including through AddCratis())
without the opt-in logs a warning that names the setting on every startup. The built-in header
handlers log a warning on the first request that carries the headers while they are not trusted.
What to do: if every request reaches your application through an ingress that strips
caller-supplied identity headers and sets its own, opt in. In a C# host, add one line to the options
you pass to AddCratis or AddCratisArc:
builder.AddCratis(options => options.TrustForwardedIdentityHeaders = true);Or in configuration, for example as the environment variable
Cratis__Arc__TrustForwardedIdentityHeaders=true:
{ "Cratis": { "Arc": { "TrustForwardedIdentityHeaders": true } }}If the application can be reached without going through such an ingress, do not opt in: configure a real authentication scheme instead.
Cratis:Arc:Introspection:TrustForwardedIdentityHeaders is now obsolete. Setting it still
turns on the host-wide TrustForwardedIdentityHeaders, so a host that already set it keeps
working. Move the setting to Cratis:Arc:TrustForwardedIdentityHeaders. Startup no longer
refuses protected catalogs behind the header scheme, because the scheme authenticates
nobody until the host opts in.
See Microsoft Identity.
Discovery endpoints require authentication outside Development
Section titled “Discovery endpoints require authentication outside Development”Who is affected: applications or tools that read the discovery endpoints of a host running
outside Development without signing in. The discovery endpoints are the command and query
catalogs (/.cratis/commands and /.cratis/queries) and identity discovery
(/.cratis/users, /.cratis/tenants and /.cratis/identity-details/schema). Command and query
invocation and /.cratis/me are not affected.
What changed: these endpoints used to be anonymous in every environment. They are now
anonymous only in Development, where Lens and the Cratis CLI read them locally. Everywhere else
they require an authenticated caller, so an anonymous request gets 401. A host outside
Development that has no way to authenticate callers, such as an ASP.NET Core host without a
default authentication scheme or an Arc.Core host without authentication handlers, does not map
them at all (404) and logs a warning that names the setting below on startup. Development is
decided by the host’s IHostEnvironment.IsDevelopment(), including environment names configured
through DOTNET_ENVIRONMENT, command-line arguments or host options. Only when no host
environment is registered does Arc fall back to ASPNETCORE_ENVIRONMENT.
What to do: nothing, if only signed-in users or local tooling read these endpoints. To
expose them anonymously as before, add one line to the options in a C# host that you pass to
AddCratis or AddCratisArc:
builder.AddCratisArc(options => options.Introspection.RequireAuthentication = false);Or set Cratis__Arc__Introspection__RequireAuthentication=false. Outside Development the host
then logs a warning on startup that the endpoints are anonymous.
Introspection.RequireAuthentication remains a bool for source compatibility. Its getter
returns false when unset, but leaving it unset selects the environment default; explicitly
assigning false opts into anonymous discovery in every environment.
Introspection.Roles now implies authentication on its own instead of needing
RequireAuthentication: true.
See Introspection.