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 ¶
- Variables
- type Client
- func (c *Client) CreateIdentity(ctx context.Context, email, displayName, role, password string) error
- func (c *Client) CreateIdentityGeneratePassword(ctx context.Context, email, displayName, role string) (string, error)
- func (c *Client) DeleteIdentity(ctx context.Context, email string) error
- func (c *Client) Enabled() bool
- func (c *Client) GetIdentity(ctx context.Context, id string) (*Identity, error)
- func (c *Client) LoginByPassword(ctx context.Context, email, password string) (*Identity, error)
- func (c *Client) Whoami(ctx context.Context, cookieHeader string) (*Identity, error)
- type Config
- type Identity
- type IdentityMetaPublic
- type IdentityTraits
- type VerifiableAddress
Constants ¶
This section is empty.
Variables ¶
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.
var ErrNoSession = errors.New("kratos: no active session")
ErrNoSession is returned by Whoami when there is no active Kratos session for the supplied cookie.
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 NewFromEnv ¶
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 ¶
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) GetIdentity ¶
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 ¶
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 ¶
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"`
// VerifiableAddresses carries Kratos's per-address verification
// state; see EmailVerified.
VerifiableAddresses []VerifiableAddress `json:"verifiable_addresses,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.
func (Identity) EmailVerified ¶ added in v0.32.1
EmailVerified reports whether the identity's trait email is a verified address. False when Kratos doesn't list it (verification disabled) or lists it unverified.
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).
type VerifiableAddress ¶ added in v0.32.1
type VerifiableAddress struct {
Value string `json:"value"`
Via string `json:"via,omitempty"`
Verified bool `json:"verified"`
}
VerifiableAddress is one of an identity's contact addresses and whether Kratos has verified it.