Skip to Content
ProvidersAuthentication

Authentication

Authentication providers handle platform login for the Gestalt server. Authentication is separate from Authorization, which decides what the caller may access, and External Credentials, which provide upstream credentials for configured connections.

How authentication providers work

When a request arrives without a valid session, Gestalt asks the configured authentication provider to begin login, redirects the user to the identity provider, and then calls the provider again to complete the callback. After that, Gestalt issues and stores its own session.

First-Party Authentication Providers

Published first-party authentication providers live under valon-technologies/gestalt-providers/auth.

ProviderUse case
github.com/valon-technologies/gestalt-providers/auth/oidcGeneric OpenID Connect providers such as Google, Okta, Auth0, Azure AD, or Keycloak

Configuring providers.authentication

providers: authentication: oidc: source: package: github.com/valon-technologies/gestalt-providers/auth/oidc version: 0.0.1-alpha.1 config: issuerUrl: https://login.example.com clientId: ... clientSecret: ...

Structured secret refs such as clientSecret.secret.provider: default are resolved through providers.secrets before the authentication provider receives its config.

To disable platform authentication entirely, omit providers.authentication.

For local development, omission is the simple default: every request is treated as the same anonymous user.

Local source during development

providers: authentication: oidc: source: ./oidc-auth/manifest.yaml config: issuerUrl: https://login.example.com clientId: ... clientSecret: ...

Building your own authentication provider

Manifest

An authentication provider manifest declares kind: authentication. You can optionally include a configSchemaPath so Gestalt validates provider config at startup.

kind: authentication source: github.com/your-org/authentication/google version: 0.0.1 displayName: Google Authentication description: Authenticate users with Google OAuth. spec: configSchemaPath: ./authentication_config.json

Interface

The authentication surface has two required methods: BeginLogin and CompleteLogin. BeginLogin returns an authorization URL that Gestalt redirects the user to. CompleteLogin exchanges callback parameters for an authenticated identity.

package googleauth import ( "context" "fmt" gestalt "github.com/valon-technologies/gestalt/sdk/go" "golang.org/x/oauth2" googleoauth "golang.org/x/oauth2/google" ) type GoogleAuth struct { clientID string clientSecret string } func New() *GoogleAuth { return &GoogleAuth{} } func (g *GoogleAuth) Configure(_ context.Context, _ string, config map[string]any) error { g.clientID, _ = config["clientId"].(string) g.clientSecret, _ = config["clientSecret"].(string) if g.clientID == "" || g.clientSecret == "" { return fmt.Errorf("clientId and clientSecret are required") } return nil } func (g *GoogleAuth) BeginLogin(_ context.Context, req *gestalt.BeginLoginRequest) (*gestalt.BeginLoginResponse, error) { cfg := &oauth2.Config{ ClientID: g.clientID, ClientSecret: g.clientSecret, RedirectURL: req.CallbackUrl, Scopes: []string{"openid", "email", "profile"}, Endpoint: googleoauth.Endpoint, } return &gestalt.BeginLoginResponse{ AuthorizationUrl: cfg.AuthCodeURL(req.HostState, oauth2.AccessTypeOffline), }, nil } func (g *GoogleAuth) CompleteLogin(ctx context.Context, req *gestalt.CompleteLoginRequest) (*gestalt.AuthenticatedUser, error) { // Exchange req.Query["code"] for a token, then fetch userinfo. return &gestalt.AuthenticatedUser{ Subject: "user-123", Email: "user@example.com", EmailVerified: true, DisplayName: "Example User", }, nil }

Optional interfaces

Two optional interfaces extend the base contract.

External token validation

External token validation lets API clients present a bearer token directly instead of going through the browser login flow. Return a user when the token is valid. Return nil, None, null, or undefined when the token is not recognized.

Implement ExternalTokenValidator on the same provider type:

import ( "context" gestalt "github.com/valon-technologies/gestalt/sdk/go" ) func (g *GoogleAuth) ValidateExternalToken(ctx context.Context, token string) (*gestalt.AuthenticatedUser, error) { if token == "" { return nil, nil } // Validate the bearer token with the upstream issuer, then map the // token claims into a Gestalt identity. return &gestalt.AuthenticatedUser{ Subject: "user-123", Email: "user@example.com", EmailVerified: true, DisplayName: "Example User", Claims: map[string]string{ "issuer": "https://accounts.google.com", }, }, nil }

Session TTL

Session TTL controls how long Gestalt persists a successful browser login. If you do not implement the optional hook, sessions default to 24 hours.

Implement SessionTTLProvider on the same provider type:

import "time" func (g *GoogleAuth) SessionTTL() time.Duration { return 8 * time.Hour }

Deploying the provider

Configure a custom authentication provider through the same providers.authentication block shown in Configuring providers.authentication. That section is the source of truth for local manifest paths, published provider release URLs, and structured secret refs. For packaging and release mechanics, see Releasing provider packages.