Help us shape the future of Go! Take the 2026 Go Developer Survey

hydra

package module
v0.0.13 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 29, 2026 License: MIT Imports: 24 Imported by: 0

README

backplane-hydra

Ory Hydra joined to a Backplane installation. Hydra stays a stock installation (official image, official chart); this service sits next to it:

  • Consent → hook hydra.Consent. Hydra sends browsers to this service's /consent. A binding decides (accept, reject, or a consent UI) and adds the claims of the tokens — typically from kratos.GetIdentity. Unbound, a trusted client (skip_consent) or a remembered consent is accepted; any other goes to settings.consent.ui_url, or is refused (consent_required).
  • Tokens → hook hydra.TokenClaims (Hydra's token hook, written into Hydra's configuration only while bound): set the extra claims of every token or refuse it.
  • Logout through Hydra lands on /logout, is accepted and published as LoggedOut — wire it to kratos.RevokeSessions to end the identity's sessions too. Consents publish ConsentGranted.
  • Admin API → activities: CreateClient (answers the secret), GetClient, ListClients, UpdateClient, PatchClient, SetClientLifespans, DeleteClient, ListConsents, RevokeConsents, RevokeLoginSessions, the login/consent/logout request steps for products with their own UI (and RejectLogoutRequest, AcceptDeviceRequest), IntrospectToken, DeleteTokens, key sets (GetKeySet, RotateKey, ImportKey, DeleteKey, DeleteKeySet), trusted issuers (ListTrustedIssuers, TrustIssuer, DeleteTrustedIssuer); client changes publish ClientCreated/Updated/Deleted.
  • Console module: Hydra's state and discovery, clients (Hydra's own JSON with completion and checks, secrets shown once, rotation, token deletion), a subject's consents and login sessions, key sets (rotation, import, deletion), trusted JWT issuers, token introspection, and a Settings page that saves revisions of this service's configuration. Every operator change is application audit.
  • Settings from the console: issuer, login/registration/error URLs, TTLs, token strategies, PKCE, claims, consent defaults, OIDC subject types, refresh rotation — live.

With Kratos

Kratos is Hydra's login provider: Hydra's settings.login_url is Kratos's login UI, and backplane-kratos's settings.oauth2_provider.url is Hydra's admin API. The consent binding gives tokens the identity's traits:

hook: hydra.Consent
steps:
  identity:
    activity: kratos.GetIdentity
    input: {id: req.subject}
result:
  id_token_claims: {email: identity.traits.email}

Who a token speaks for: pkg/auth

A service verifies Hydra's access tokens without a token cache, so every replica answers alike:

  • JWT access tokens (the default strategy): verified locally against Hydra's public keys (<issuer>/.well-known/jwks.json) — no call per request. A revoked token stays valid until it expires (ttl.access_token). An ID token, signed with the same keys, is refused: an access token carries client_id and scp, an ID token auth_time (and at_hash, nonce), which no consent can remove.
  • Introspection: any access token, opaque or JWT, asked of Hydra's admin API on every request — no cache: a revocation shows on the next request. Refresh tokens are refused.
tokens, _ := auth.NewTokens(auth.TokensOptions{Issuer: "https://auth.example.com/"})
introspection, _ := auth.NewIntrospection("http://hydra:4445", nil, nil)
a := auth.Authenticator{Tokens: tokens, Introspection: introspection}

mux.Handle("/api/", a.Required(api))
// in a handler:
who, _ := auth.FromContext(r.Context()) // who.Subject, who.ClientID, who.HasScope("orders.read"), who.Extra

Audience: without Audience (and Introspection.WithAudience) a token Hydra issued for another API of the same installation is accepted too — its signature and issuer are still checked. Hydra issues aud: [] unless a client asks for an audience, so the check is opt-in: set it when one Hydra serves several APIs.

The claims the consent and hydra.TokenClaims add are in Extra (Hydra's ext), and in Claims too when they are mirrored to the top level. The only cache is of the public keys: fetched on first use, again on a token with an unknown kid (at most once per 30s) and in the background every 10m; when the keys cannot be fetched, the last good set keeps verifying.

How Hydra picks up the settings

As with backplane-kratos: Hydra runs with the deployment's file and an overlay this service writes (hydra serve all -c base.yml -c overlay.yml) on a volume shared with this sidecar; deployments/examples/helm-values.yaml does it with the official chart. The overlay owns urls.consent and urls.logout (this service's endpoints), the token hook, and what the settings model; dsn, serve, secrets stay the deployment's.

Configuration

Key
hydra.admin_url, hydra.public_url Hydra's APIs (default 127.0.0.1:4445/4444)
public_url This service as browsers reach it (Hydra redirects them to its /consent, /logout)
callbacks.listen, callbacks.url, callbacks.key Where Hydra calls the token hook (default :8091)
overlay, overlay_mode The overlay file and its permissions
settings Live: the Hydra settings above, edited on the module's Settings page
pairwise_salt Live secret kept apart from the settings

Develop

make configure configure-web   # tools into ./bin, web dependencies
make gen web build             # protos, console module, binary
make test                      # unit tests
make it-up it                  # a whole OAuth 2.0 flow against a real Hydra (docker)

Hydra v26.2.0; the overlay is validated against its configuration schema before it is written.

Documentation

Overview

Package hydra is backplane-hydra as a library: Main runs it. It joins an Ory Hydra installation to Backplane: consent and token claims become hooks, logouts and consents events, the admin API activities and a console module, and the settings an operator edits are written to a configuration overlay Hydra reloads.

Index

Constants

This section is empty.

Variables

View Source
var ErrNoKey = errors.New("hydra: callbacks.key or backplane.internal_secret is required")

ErrNoKey: neither a callbacks key nor an internal secret is configured.

View Source
var ErrOverlayMode = errors.New("hydra: overlay_mode must be octal permission bits like 0640")

ErrOverlayMode: overlay_mode is not octal permission bits.

View Source
var ErrPublicURL = errors.New("hydra: public_url is required (Hydra redirects browsers to its /consent)")

ErrPublicURL: browsers must reach the consent endpoint.

Functions

func Main

func Main()

Main runs backplane-hydra until a signal stops it, exiting on error.

func Run

func Run(ctx context.Context) error

Run runs backplane-hydra until ctx ends or a signal stops it.

Types

type Callbacks

type Callbacks struct {
	Listen string `json:"listen" schemapb:"default=:8091"`
	// URL is the listener as Hydra reaches it.
	URL string `json:"url" schemapb:"default=http://127.0.0.1:8091"`
	// Key authenticates Hydra; empty: derived from the internal secret.
	Key config.Secret `json:"key,omitempty"`
}

Callbacks listener.

type Config

type Config struct {
	config.Backplane `json:"backplane"`

	// Hydra is the installation.
	Hydra Connection `json:"hydra"`
	// PublicURL is this service's public API as browsers reach it: Hydra
	// redirects them to its /consent and /logout.
	PublicURL string `json:"public_url" schemapb:"description=This service's public URL as browsers reach it"`
	// Callbacks is the listener Hydra calls (the token hook).
	Callbacks Callbacks `json:"callbacks"`
	// Overlay is the file Hydra loads after its own (-c base -c overlay),
	// shared with the Hydra container; empty: nothing is written.
	Overlay string `json:"overlay,omitempty" schemapb:"description=Path of the overlay file Hydra loads (empty: snippets only)"`
	// OverlayMode is the file's permission bits (octal).
	OverlayMode string `json:"overlay_mode,omitempty" schemapb:"default=0644"`
	// PairwiseSalt salts pairwise subject identifiers; live, kept apart
	// from the settings.
	PairwiseSalt config.Live[config.Secret] `json:"pairwise_salt,omitempty" schemapb:"description=Salt of pairwise subject identifiers"`
	// Settings are Hydra's settings rendered into the overlay; live.
	Settings config.Live[overlay.Settings] `json:"settings"`
}

Config is the whole configuration: file (BACKPLANE_CONFIG_FILE) < env HYDRA_* (BACKPLANE_* for the SDK block) < Consul KV for Live fields.

func (*Config) Validate

func (c *Config) Validate() error

Validate what the schema cannot: the settings must render into a configuration Hydra accepts.

type Connection

type Connection struct {
	AdminURL  string                   `json:"admin_url"         schemapb:"default=http://127.0.0.1:4445"`
	PublicURL string                   `json:"public_url"        schemapb:"default=http://127.0.0.1:4444"`
	Headers   map[string]config.Secret `json:"headers,omitempty"`
	Timeout   time.Duration            `json:"timeout"           schemapb:"default=10s"`
}

Connection to Hydra.

type State

type State struct {
	Hydra      deps.Dependency[ory.Client]
	Flows      *flows.Flows
	Applier    *apply.Applier
	Activities *activities.Activities
	Admin      *admin.Admin
	// contains filtered or unexported fields
}

State is the service's tree.

Directories

Path Synopsis
cmd
hydra command
Command hydra runs backplane-hydra.
Command hydra runs backplane-hydra.
internal
activities
Package activities offers Hydra's admin API to wiring: OAuth 2.0 clients, login, consent and logout requests (for products with their own UI), consent and login sessions, token introspection and keys.
Package activities offers Hydra's admin API to wiring: OAuth 2.0 clients, login, consent and logout requests (for products with their own UI), consent and login sessions, token introspection and keys.
admin
Package admin is the console module's API: the Hydra installation, its clients, consents, keys and trusted issuers.
Package admin is the console module's API: the Hydra installation, its clients, consents, keys and trusted issuers.
apply
Package apply keeps the overlay file equal to the settings and the bound hooks: rendered at start, after every settings change and every binding change, and every resync interval (a file someone replaced).
Package apply keeps the overlay file equal to the settings and the bound hooks: rendered at start, after every settings change and every binding change, and every resync interval (a file someone replaced).
flows
Package flows serves what Hydra hands over: the consent and logout steps of a browser's OAuth 2.0 flow (hook Consent, event LoggedOut) and the token hook (hook TokenClaims).
Package flows serves what Hydra hands over: the consent and logout steps of a browser's OAuth 2.0 flow (hook Consent, event LoggedOut) and the token hook (hook TokenClaims).
ory
Package ory is a small client of an Ory Hydra installation: its admin API (clients, consent and login requests and sessions, tokens, keys, trusted issuers).
Package ory is a small client of an Ory Hydra installation: its admin API (clients, consent and login requests and sessions, tokens, keys, trusted issuers).
overlay
Package overlay renders the Hydra configuration file backplane-hydra owns: the settings an operator edits in the console, the consent and logout endpoints it serves, and the token hook while it is bound.
Package overlay renders the Hydra configuration file backplane-hydra owns: the settings an operator edits in the console, the consent and logout endpoints it serves, and the token hook while it is bound.
ui
Package ui carries the console module: web/dist/plugin copied here by `make web` and embedded into the binary.
Package ui carries the console module: web/dist/plugin copied here by `make web` and embedded into the binary.
pkg
auth
Package auth tells a service who made a request from an OAuth2 access token Ory Hydra issued.
Package auth tells a service who made a request from an OAuth2 access token Ory Hydra issued.
proto

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL