Make auth cookie SameSite configurable

Add same-site to auth cookie config with lax as the default,
PROBOD_AUTH_COOKIE_SAMESITE bootstrap mapping, and validation
that rejects none unless Secure is enabled.

Signed-off-by: Cursor Agent <cursoragent@cursor.com>

Co-authored-by: Bryan FRIMIN <bryan@frimin.fr>
This commit is contained in:
Cursor Agent
2026-07-29 16:37:28 +00:00
committed by Bryan Frimin
parent cd6c46212a
commit 62d0ab68c4
9 changed files with 266 additions and 26 deletions

View File

@@ -134,6 +134,7 @@ func New() *Implm {
Duration: 24,
Domain: "localhost",
Secure: true,
SameSite: CookieSameSiteLax,
},
DisableSignup: false,
InvitationConfirmationTokenValidity: 3600,
@@ -280,6 +281,18 @@ func (impl *Implm) Run(
return fmt.Errorf("cannot get cookie secret bytes: %w", err)
}
if err := impl.cfg.Auth.Cookie.Validate(); err != nil {
rootSpan.RecordError(err)
return fmt.Errorf("cannot validate auth cookie config: %w", err)
}
authCookieMaxAge := int(time.Duration(impl.cfg.Auth.Cookie.Duration) * time.Hour)
authCookie, err := authSecureCookieConfig(impl.cfg.Auth.Cookie, authCookieMaxAge)
if err != nil {
rootSpan.RecordError(err)
return fmt.Errorf("cannot configure auth cookie: %w", err)
}
awsConfig, err := awsconfig.NewConfig(
l,
httpclient.DefaultPooledClient(
@@ -768,16 +781,7 @@ func (impl *Implm) Run(
CustomDomainCname: impl.cfg.CustomDomains.CnameTarget,
TokenSecret: impl.cfg.Auth.Cookie.Secret,
Logger: l.Named("http.server"),
Cookie: securecookie.Config{
Name: impl.cfg.Auth.Cookie.Name,
Domain: impl.cfg.Auth.Cookie.Domain,
Path: "/",
MaxAge: int(time.Duration(impl.cfg.Auth.Cookie.Duration) * time.Hour),
Secret: impl.cfg.Auth.Cookie.Secret,
Secure: impl.cfg.Auth.Cookie.Secure,
HTTPOnly: true,
SameSite: http.SameSiteLaxMode,
},
Cookie: authCookie,
},
)
if err != nil {
@@ -796,17 +800,8 @@ func (impl *Implm) Run(
File: fileManagerService,
ESign: esignService,
Mailman: mailmanService,
Cookie: securecookie.Config{
Name: impl.cfg.Auth.Cookie.Name,
Domain: impl.cfg.Auth.Cookie.Domain,
Path: "/",
MaxAge: int(time.Duration(impl.cfg.Auth.Cookie.Duration) * time.Hour),
Secret: impl.cfg.Auth.Cookie.Secret,
Secure: impl.cfg.Auth.Cookie.Secure,
HTTPOnly: true,
SameSite: http.SameSiteLaxMode,
},
TokenSecret: impl.cfg.Auth.Cookie.Secret,
Cookie: authCookie,
TokenSecret: impl.cfg.Auth.Cookie.Secret,
GraphQLLimits: gqlutils.Limits{
ParserTokenLimit: impl.cfg.Api.GraphQL.ParserTokenLimit,
ComplexityLimit: impl.cfg.Api.GraphQL.ComplexityLimit,
@@ -1604,3 +1599,21 @@ func oauth2ServerOptions(cfg OAuth2ServerConfig) []oauth2.Option {
return opts
}
func authSecureCookieConfig(c CookieConfig, maxAgeSeconds int) (securecookie.Config, error) {
sameSite, err := c.HTTPSameSite()
if err != nil {
return securecookie.Config{}, err
}
return securecookie.Config{
Name: c.Name,
Domain: c.Domain,
Path: "/",
MaxAge: maxAgeSeconds,
Secret: c.Secret,
Secure: c.Secure,
HTTPOnly: true,
SameSite: sameSite,
}, nil
}