kratos

package
v0.19.13 Latest Latest
Warning

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

Go to latest
Published: May 18, 2026 License: MIT Imports: 13 Imported by: 0

Documentation

Overview

Package kratos provides admin-side provisioning of Ory Kratos identities via the Kratos admin API.

Wire flow:

Admin → POST /api/admin/users
  rivolt API
    └─ kratos.Client.CreateIdentity
         └─ POST {AdminURL}/admin/identities
              ├─ traits.email = email
              ├─ traits.display_name = displayName
              ├─ schema_id = "rivolt_user"
              └─ credentials.password.config.password = <plaintext>

Kratos hashes the password server-side (argon2id by default) and stores the identity in its Postgres DB. No Vault round-trip, no ExternalSecret refresh, no file-watcher polling — the identity is usable in <100 ms.

All operations are idempotent: CreateIdentity returns an error on 409 Conflict (existing email), DeleteIdentity is a no-op on 404.

The package is a no-op when not configured (NewFromEnv returns a nil client when KRATOS_ADMIN_URL is unset). Callers must check Enabled() before relying on it.

Index

Constants

This section is empty.

Variables

View Source
var ErrInvalidCredentials = errors.New("kratos: invalid credentials")

ErrInvalidCredentials is returned by LoginByPassword when Kratos rejects the email/password pair. Callers should surface a generic 401 to keep the response opaque.

View Source
var ErrNoSession = errors.New("kratos: no active session")

ErrNoSession is returned by Whoami when there is no active Kratos session for the supplied cookie.

View Source
var ErrNotFound = errors.New("kratos: identity not found")

ErrNotFound is returned by admin lookups (GetIdentity) when the requested identity does not exist (Kratos returns 404). Distinct from ErrNoSession (no active session) and ErrInvalidCredentials (login failed): callers usually treat ErrNotFound as a hard 4xx because it means the subject we got from Hydra is stale.

Functions

This section is empty.

Types

type Client

type Client struct {
	// contains filtered or unexported fields
}

Client talks to the Kratos admin API. The zero value is not usable; build via NewFromEnv or New. A nil *Client is safe to call — Enabled() returns false and all mutating methods return errors.

func New

func New(cfg Config) (*Client, error)

New builds a Client from an explicit Config. Returns an error if AdminURL is empty.

func NewFromEnv

func NewFromEnv() (*Client, error)

NewFromEnv builds a Client from environment variables. Returns a nil *Client (and nil error) when KRATOS_ADMIN_URL is unset, so callers can wire up the IdP unconditionally and rely on Enabled() to gate behavior.

Recognised env vars:

KRATOS_ADMIN_URL          — required to enable
KRATOS_PUBLIC_URL         — optional; enables LoginByPassword/Whoami
KRATOS_SCHEMA_ID          — defaults to "rivolt_user"
KRATOS_TIMEOUT            — Go duration; default 10s
KRATOS_GROUPS_ADMIN       — CSV; default "admins"
KRATOS_GROUPS_USER        — CSV; default "users"

func (*Client) CreateIdentity

func (c *Client) CreateIdentity(ctx context.Context, email, displayName, role, password string) error

CreateIdentity provisions a new identity with a caller-supplied password. Returns an error if an identity with this email already exists (Kratos returns 409 Conflict).

func (*Client) CreateIdentityGeneratePassword

func (c *Client) CreateIdentityGeneratePassword(ctx context.Context, email, displayName, role string) (string, error)

CreateIdentityGeneratePassword provisions a new identity with a freshly generated random password and returns the password to the caller. The password is never stored by Rivolt.

func (*Client) DeleteIdentity

func (c *Client) DeleteIdentity(ctx context.Context, email string) error

DeleteIdentity removes the identity matching the given email. No-op when the identity does not exist (404). Email is the canonical login identifier in our schema.

func (*Client) Enabled

func (c *Client) Enabled() bool

Enabled reports whether the client is configured. Safe on nil.

func (*Client) GetIdentity

func (c *Client) GetIdentity(ctx context.Context, id string) (*Identity, error)

GetIdentity fetches an identity by its Kratos id (UUID). The `id` is the value returned from LoginByPassword and the same value Hydra hands back in the consent challenge's `subject` field. Returns ErrNotFound when the identity does not exist.

Used at consent-accept time to look up the email + display name traits of the just-authenticated identity, so we can pour them into Hydra's id_token Session payload — otherwise downstream OIDC clients only see a bare `sub` claim and have to round-trip /userinfo for anything human.

func (*Client) LoginByPassword

func (c *Client) LoginByPassword(ctx context.Context, email, password string) (*Identity, error)

LoginByPassword authenticates a user against Kratos's API login flow (no cookies, no CSRF). On success returns the Kratos identity (the .id is what we feed to Hydra's accept-login as `subject`).

Returns ErrInvalidCredentials when Kratos rejects the password pair, so callers can surface a 401 to the browser without leaking whether the email or the password was wrong.

func (*Client) Whoami

func (c *Client) Whoami(ctx context.Context, cookieHeader string) (*Identity, error)

Whoami calls /sessions/whoami with the supplied cookie header (forwarded verbatim from the inbound request). Returns the identity if the session is active; ErrNoSession when Kratos returns 401 or the cookie is missing.

The cookie value is the raw "Cookie:" header from the user's request — Kratos pulls its own session cookie out of it.

type Config

type Config struct {
	// AdminURL is the Kratos admin API base, e.g.
	// http://ory-kratos-admin.ory.svc:80. Required (and the only
	// required field for in-cluster identity-provisioning setups).
	AdminURL string

	// PublicURL is the Kratos public API base, e.g.
	// http://ory-kratos-public.ory.svc:80. Optional; only needed
	// when the caller uses LoginByPassword or Whoami (the Hydra
	// custom login UI in internal/api/hydra.go does).
	PublicURL string

	// SchemaID is the identity schema to use; matches the id in
	// kratos.config.identity.schemas[].id in the Helm values.
	SchemaID string

	// Timeout for individual HTTP calls to the admin API.
	Timeout time.Duration

	// AdminGroups / UserGroups are kept here so call-sites have a
	// single place to map roles to OIDC group strings. Kratos schemas
	// don't have a built-in "groups" concept, so we store the role
	// in a metadata_public
	// field. Use the first entry of each slice as the canonical name.
	AdminGroups []string
	UserGroups  []string

	// HTTPClient is optional; one is constructed from Timeout when nil.
	HTTPClient *http.Client
}

Config holds runtime knobs for the Kratos provisioning client.

Defaults match our in-cluster layout (see rivolt-infra apps/ory/kratos/values.yaml) so a typical deployment only needs to set AdminURL.

type Identity

type Identity struct {
	ID             string             `json:"id"`
	Traits         IdentityTraits     `json:"traits"`
	MetadataPublic IdentityMetaPublic `json:"metadata_public,omitempty"`
}

Identity is the subset of an identity object we surface from the public Kratos API. It mirrors the fields the admin POST /admin/ identities response contains, but only the parts the Hydra login handler needs to make a "subject" decision.

type IdentityMetaPublic

type IdentityMetaPublic struct {
	Role string `json:"role,omitempty"`
}

IdentityMetaPublic carries fields we attach to the identity for display / authorization but don't want users to mutate via self-service flows. Kratos guarantees `metadata_public` is only writable from the admin API.

Today we use it for `role` (admin / user), which the consent handler projects into a `groups` claim on the id_token so downstream OIDC clients (ArgoCD, Grafana, Rivolt) can run their own RBAC off it.

type IdentityTraits

type IdentityTraits struct {
	Email       string `json:"email"`
	DisplayName string `json:"display_name,omitempty"`
}

IdentityTraits matches our rivolt_user schema (email + display).

Jump to

Keyboard shortcuts

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