Skip to content

Security Overview — Auth, Encryption & Audit

The base security package providing the ICurrentUserService abstraction and ActorKind enum. Used by every module that needs to know “who is calling” — audit trails, tenant resolution, authorization checks.

ProblemModuleWhen to use
You need to verify who is calling your APIAuthenticationAlways — choose the provider package matching your identity platform (Keycloak, Entra ID, or Cognito)
Users/roles need different access levelsAuthorizationWhen permissions change at runtime or differ per tenant
You store PII that must be encrypted at restField-level EncryptionGDPR Art. 32, ISO 27001 A.8.24 — national IDs, medical records, bank accounts
You need external secret/key managementVault & EncryptionProduction environments — never store encryption keys in config files
You manage user accounts (CRUD, sync)IdentityWhen your API owns user lifecycle (registration, deactivation, profile sync)
Users can request data export or deletionPrivacyGDPR Art. 15–18 — any app handling EU personal data
Your SPA uses cookie-based auth with consentCookiesBrowser-based apps with GDPR cookie consent requirements
Your SPA should never touch tokensBFFSPAs where tokens must stay server-side (XSS mitigation, OAuth BCP)
You self-host your identity providerOpenIddictWhen you need full control over OIDC flows, token issuance, and user management
You need FAPI 2.0 financial-grade securityFAPI 2.0Banking, PSD2, or any high-security API requiring PAR + DPoP + private_key_jwt
  • DirectoryGranit.Users/ Base abstractions (ICurrentUserService, ActorKind)
PackageRoleDepends on
Granit.UsersICurrentUserService, ActorKindGranit

The core abstraction for accessing the authenticated actor. Injected everywhere audit fields, tenant resolution, or authorization checks need to know “who is calling.”

public interface ICurrentUserService
{
string? UserId { get; }
string? UserName { get; }
string? Email { get; }
string? FirstName { get; }
string? LastName { get; }
bool IsAuthenticated { get; }
ActorKind ActorKind { get; }
bool IsMachine { get; }
string? ApiKeyId { get; }
IReadOnlyList<string> GetRoles();
bool IsInRole(string role);
}

ActorKind distinguishes between User (human), ExternalSystem (API key / service account), and System (background jobs, scheduled tasks).

The complete authentication and authorization stack is documented in dedicated pages:

graph TD
    S[Granit.Users] --> C[Granit]
    JWT[Granit.Authentication.JwtBearer] --> S
    KC[Granit.Authentication.JwtBearer.Keycloak] --> JWT
    EID[Granit.Authentication.JwtBearer.EntraId] --> JWT
    CG[Granit.Authentication.JwtBearer.Cognito] --> JWT
    GC[Granit.Authentication.JwtBearer.GoogleCloud] --> JWT
    DPOP[Granit.Authentication.DPoP] --> JWT
    AZ[Granit.Authorization] --> S
    AZ --> CA[Granit.Caching]
    AZEF[Granit.Authorization.EntityFrameworkCore] --> AZ
    AZEF --> P[Granit.Persistence]
    BFF[Granit.Bff] --> S
    BFFE[Granit.Bff.Endpoints] --> BFF
    BFFY[Granit.Bff.Yarp] --> BFF
  • Authentication — JWT Bearer, Keycloak, Entra ID, Cognito, Google Cloud, DPoP
  • BFF — Backend For Frontend pattern for SPAs, session management, YARP proxy
  • OpenIddict — self-hosted OIDC server, user management, FAPI 2.0
  • Authorization — RBAC permissions, dynamic policy provider
  • Identity — user management, Keycloak Admin API, user cache
  • Privacy — GDPR compliance, right to erasure
  • CoreICurrentTenant, exception hierarchy
  • PersistenceAuditedEntity base class, interceptors