Skip to content

Cookies — Secure Cookie Management

Granit.Http.Cookies enforces a strict cookie registry: every cookie must be declared at startup with a consent category. Writing an undeclared cookie throws UnregisteredCookieException. Consent is resolved per-category via a pluggable IConsentResolver.

PackageRoleDepends on
Granit.Http.CookiesCookie registry, consent enforcement, GPC signalGranit
Granit.Http.Cookies.KlaroKlaro CMP consent resolverGranit.Http.Cookies
Granit.Http.Cookies.EndpointsCookie configuration API endpointGranit.Http.Cookies
Granit.Privacy.Regulations.CookiesRegulation-aware consent model bridgeGranit.Http.Cookies, Granit.Privacy.Regulations
[DependsOn(typeof(GranitHttpCookiesModule))]
public class AppModule : GranitModule
{
public override void ConfigureServices(ServiceConfigurationContext context)
{
context.Services.AddGranitCookies(cookies =>
{
cookies.RegisterCookie(new CookieDefinition(
"session_id", CookieCategory.StrictlyNecessary,
1, true, "Session identification"));
cookies.RegisterCookie(new CookieDefinition(
"analytics_consent", CookieCategory.Analytics,
365, false, "Analytics tracking preference"));
cookies.UseKlaro();
});
}
}

Granit modules that introduce cookies auto-declare them via ICookieDefinitionContributor. The cookie registry collects all contributors at first resolution — no manual declaration needed for framework cookies.

ModuleCookies auto-registeredContributor
Granit.Http.Cookies__Host-xsrf / .xsrf (dev)AntiforgeryCookieDefinitionContributor
Granit.OpenIddict.EntityFrameworkCore__Host-id / .id (dev), __Host-id-2fa / .id-2fa, __Host-id-ext / .id-extIdentityCookieDefinitionContributor
Granit.Http.Cookies.Klaroklaro (configurable)KlaroCookieDefinitionContributor
Granit.Bff.Endpoints__Host-bff-{name} / .bff-{name} (dev)Runtime registration in MapGranitBff()
Granit.Privacy.Endpoints_optout_idRuntime registration in MapGranitPrivacy()
internal sealed class MyCookieContributor : ICookieDefinitionContributor
{
public IEnumerable<CookieDefinition> GetCookieDefinitions()
{
yield return new CookieDefinition(
"my_cookie", CookieCategory.StrictlyNecessary,
1, true, "Purpose description")
{ IsEssential = true };
}
}

Register it in your module’s ConfigureServices:

context.Services.AddSingleton<ICookieDefinitionContributor, MyCookieContributor>();

The antiforgery cookie (__Host-xsrf) is auto-registered by GranitHttpCookiesModule. The session cookie is opt-in because AddSession() is not always used. Call RegisterSessionCookie() in hosts that enable session middleware:

context.Services.AddGranitCookies(cookies =>
{
cookies.RegisterSessionCookie();
});
CategoryConsent requiredDescription
StrictlyNecessaryNoSession, CSRF, authentication, opt-out tracking
PreferencesYesLanguage, theme, layout
AnalyticsYesUsage tracking (first-party)
MarketingYesAdvertising, retargeting
SaleOrSharingYesCCPA “Do Not Sell or Share” — third-party data sharing

Always use IGranitCookieManager instead of IResponseCookies:

public class SessionService(IGranitCookieManager cookieManager)
{
public async Task SetSessionCookieAsync(
HttpContext httpContext, string sessionId)
{
// Checks registry, verifies consent, applies security defaults
await cookieManager.SetCookieAsync(
httpContext, "session_id", sessionId)
.ConfigureAwait(false);
}
}

Security defaults applied automatically:

  • Secure = true (HTTPS only)
  • SameSite = Lax (CSRF protection, configurable per cookie)
  • MaxAge calculated from RetentionDays
  • HttpOnly per cookie definition
{
"Cookies": {
"ThrowOnUnregistered": true,
"DefaultRetentionDays": 365,
"ThirdPartyServices": [
{
"Name": "Google Analytics",
"Category": "Analytics",
"CookiePatterns": ["_ga*", "_gid"]
}
]
}
}
CategoryKey typesPackage
ModulesGranitHttpCookiesModule, GranitHttpCookiesKlaroModule
RegistryICookieRegistry, CookieDefinition, CookieCategory, GranitCookiesBuilderGranit.Http.Cookies
ContributorsICookieDefinitionContributorGranit.Http.Cookies
ManagerIGranitCookieManager, IConsentResolverGranit.Http.Cookies
GPCIGlobalPrivacyControlSignal, ICookieConsentModelProvider, ConsentModelInfoGranit.Http.Cookies
KlaroKlaroConsentResolver, KlaroOptionsGranit.Http.Cookies.Klaro