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.
| Provider | Use case |
|---|---|
github.com/valon-technologies/gestalt-providers/auth/oidc | Generic 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.jsonInterface
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.
Go
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.
Go
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.
Go
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.
What To Read Next
- Secrets: secret managers for authentication provider config
- Configuration: full config examples including
providers.authentication - Built-in Providers: first-party authentication reference