| name | auth-and-identity |
| description | Use this skill when asked to set up authentication, authorization, or identity in a Cratis Arc project — backend, frontend, or both. Covers implementing identity providers, protecting commands/queries with authorization attributes, integrating Microsoft Identity Platform, connecting backend identity to React frontends, and local development testing with generated principals. Also covers customizing IProvideIdentityDetails for enriching identity from databases, blocking users, multi-tenant identity, user preferences, and modifying identity at runtime. Use this whenever the user mentions auth, login, roles, permissions, identity details, user context, protecting endpoints, identity provider customization, or anything related to who the user is and what they can access. |
Auth & Identity in Cratis Arc
This skill covers the full auth and identity stack in a Cratis Arc application. Read the relevant reference files below for detailed API usage.
Read the relevant instruction files first. This skill references concepts from the core copilot instructions in .github/copilot-instructions.md. If you need details on vertical slices, commands, queries, or proxy generation, consult those instructions.
Architecture Overview
Identity and auth in Arc follow a cookie-first, convention-based pattern:
Frontend (React) Backend (ASP.NET Core)
───────────────── ──────────────────────
<IdentityProvider> app.MapIdentityProvider()
└── useIdentity() hook └── GET /.cratis/me
│ │
├─ 1. Read .cratis-identity cookie │
└─ 2. If no cookie → fetch /.cratis/me │
▼
AuthenticationMiddleware
└── IAuthenticationHandler[]
│ sets HttpContext.User
▼
IIdentityProviderResultHandler
└── IProvideIdentityDetails.Provide()
│
▼
IdentityProviderResult
→ JSON response
→ .cratis-identity cookie (base64)
Authorization:
[Authorize] / [Roles("Admin")] / [AllowAnonymous]
└── AuthorizationEvaluator checks per command/query
Key design decisions:
- The
.cratis-identity cookie is HttpOnly=false so the frontend JavaScript can read it directly — no extra HTTP call needed on page load.
- Identity details are base64-encoded JSON in the cookie, automatically decoded by the frontend
IdentityProvider.
- Only one
IProvideIdentityDetails implementation is allowed per application (auto-discovered). If none exists, a default provider grants access to everyone.
- Cratis has its own
[Authorize], [AllowAnonymous], and [Roles] attributes in Cratis.Arc.Authorization — these are distinct from ASP.NET Core's and are evaluated by AuthorizationEvaluator in the command and query pipeline.
Decision Tree — Which Reference to Read
Use this decision tree to determine which reference file(s) to read based on the user's task:
For full-stack tasks, read in this order:
references/backend-identity.md — identity provider and startup
references/authentication.md — how users are authenticated
references/authorization.md — protecting commands and queries
references/frontend.md — consuming identity in the UI
references/local-development.md — testing without real infrastructure
Quick-Start: Full-Stack Identity Setup
This is the minimum checklist for an application with identity. Read the reference files for details on each step.
Backend
- Details record: Define a C# record for application-specific user information
- Identity provider: Implement
IProvideIdentityDetails<TDetails> (auto-discovered, one per app)
- Startup: Call
app.MapIdentityProvider() to register GET /.cratis/me
- Authentication: Add
AddMicrosoftIdentityPlatformIdentityAuthentication() or implement IAuthenticationHandler
- Authorization: Add
[Authorize] / [Roles] / [AllowAnonymous] attributes from Cratis.Arc.Authorization to commands and queries
Frontend
- Provider: Wrap app root with
<IdentityProvider> from @cratis/arc.react/identity
- Hook: Use
useIdentity<TDetails>() to access identity anywhere in the component tree
- Roles: Use
identity.isInRole('Admin') for UI-level role gating
Proxy Generation
- Using
IProvideIdentityDetails<TDetails> (generic) enables automatic TypeScript type generation at dotnet build time — the generated types can be imported in the frontend for end-to-end type safety.
Critical Rules
These rules are frequently violated — always enforce them:
- One identity provider per app: Only one
IProvideIdentityDetails implementation is allowed. Multiple throws MultipleIdentityDetailsProvidersFound.
- Use Cratis attributes, not ASP.NET Core's:
[Authorize], [Roles], [AllowAnonymous] must come from Cratis.Arc.Authorization, not Microsoft.AspNetCore.Authorization.
- Never combine
[Authorize] and [AllowAnonymous] on the same target: This throws AmbiguousAuthorizationLevel.
- Prefer the generic interface: Use
IProvideIdentityDetails<TDetails> over IProvideIdentityDetails to enable proxy generation.
- Auto-discovery: Both
IProvideIdentityDetails and IAuthenticationHandler implementations are auto-discovered — no DI registration needed.
- Frontend role checks are UX, not security:
isInRole() on the frontend hides UI elements. The backend [Roles] attribute is the actual security boundary.
- Build before frontend: TypeScript proxy types for identity details are generated by
dotnet build. The backend must compile before the frontend can import them.
Common Code Patterns
Protecting a command with roles
[Command]
[Roles("Admin")]
public record PromoteUser(UserId Id)
{
public void Handle(IUserService users) => users.Promote(Id);
}
Conditionally rendering UI based on roles
const identity = useIdentity();
return identity.isInRole('Admin')
? <AdminPanel />
: <AccessDenied />;
Modifying identity at runtime (stateless selections)
public class SetDepartment(IIdentityProviderResultHandler identityHandler)
{
public async Task Handle(string department) =>
await identityHandler.ModifyDetails<UserDetails>(
details => details with { SelectedDepartment = department });
}
Reference Documentation
Skill references (detailed implementation guidance)
- Backend Identity Provider —
IProvideIdentityDetails, IdentityProviderContext, cookie mechanics, proxy generation, ModifyDetails
- Authentication —
IAuthenticationHandler, AuthenticationResult, Microsoft Identity Platform, combining handlers
- Authorization —
[Authorize], [Roles], [AllowAnonymous], inheritance rules, fallback policies
- Frontend Identity — React
IdentityProvider, useIdentity(), MVVM, core identity, role checking
- Local Development — Generating principals, ModHeader, cookie fallback, dev testing
Project documentation