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
You resolve client IPs to a locationIP GeolocationSession enrichment, fraud heuristics — with GDPR-safe, HMAC-keyed caching
You detect suspicious / hijacked sessionsUser SessionsImpossible-travel, new-device, new-country anomaly detection (AI + heuristics)

The core actor abstractions ship inside the foundation Granit package — there is no separate Granit.Users NuGet. ICurrentUserService, ActorKind, and the audit identity primitives all live under the Granit.Users namespace within Granit.

Namespace (within Granit)Role
Granit.UsersICurrentUserService, ActorKind, SystemCurrentUserService

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
    C[Granit] -->|namespace Granit.Users| ICUS[ICurrentUserService]
    JWT[Granit.Authentication.JwtBearer] --> C
    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] --> C
    AZ --> CA[Granit.Caching]
    AZEF[Granit.Authorization.EntityFrameworkCore] --> AZ
    AZEF --> P[Granit.Persistence]
    BFF[Granit.Bff] --> C
    BFFE[Granit.Bff.Endpoints] --> BFF
    BFFY[Granit.Bff.Yarp] --> BFF
  • Authentication — JWT Bearer, Keycloak, Entra ID, Cognito, Google Cloud, DPoP
  • API Keys — service-to-service authentication, rotation, expiry scanner, lifecycle notifications
  • 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
  • IP Geolocation — source-agnostic IP → location, HMAC-keyed caching
  • User Sessions — session anomaly detection, risk scoring, suspicious-session events
  • Privacy — GDPR compliance, right to erasure
  • CoreICurrentTenant, exception hierarchy
  • PersistenceAuditedEntity base class, interceptors
  • Blog: NIS2-ready .NET applications — how Granit’s security primitives map to NIS2 controls
  • Blog: SOC 2 Type 2-ready SaaS with Granit — the controls and audit trail you get out of the box