Getting started
tinyguard is a self-contained OpenID Connect / OAuth2 identity provider: authorization-code (+PKCE), client-credentials, refresh, and device flows; WebAuthn passkeys; dynamic client registration; backchannel logout; an admin/users REST API with API keys, roles, and groups; an event and notification system; Argon2id password policies; and JWKS rotation with a built-in React admin console.
Prerequisites
Section titled “Prerequisites”- Docker (or any OCI runtime) and access to
registry.tinyfactory.ai. - For Kubernetes, Helm 3.8 or newer — see Kubernetes.
docker login registry.tinyfactory.aiRun it locally
Section titled “Run it locally”The published image contains the provider and the admin console, and its default command starts a demo configuration (HTTP on port 8080, embedded storage). Generate a secrets file first, then start the server:
IMAGE=registry.tinyfactory.ai/tinyblox/guard:0.3.2
docker run --rm --user "$(id -u):$(id -g)" -v "$PWD:/work" -w /work \ "$IMAGE" generate-secrets --output secrets.toml
docker run -d --name tinyguard -p 8080:8080 \ -v "$PWD/secrets.toml:/app/secrets.toml:ro" \ -v tinyguard-data:/app/data \ "$IMAGE"Point a browser at http://localhost:8080/auth/v1/ — the admin console loads
from the same origin. The initial administrator password is printed once to
docker logs tinyguard on first start (with a fresh data volume). On macOS,
mount the secrets file from a non-symlinked path — /tmp is symlinked and
bind-mounts a directory instead of the file.
For a quick throwaway instance, -e GUARD_LOCAL_TEST=true runs the server with the
bundled local demo configuration: unsafe by design, loopback-bound HTTPS on
port 8443 with generated self-signed material, embedded storage in a scratch
directory, public docs, and FedCM enabled.
CLI subcommands
Section titled “CLI subcommands”The image’s entrypoint is the idp-server binary, so every subcommand runs as
docker run --rm <image> <subcommand> …; mount a working directory when a
subcommand reads or writes files. Defaults are ./config.toml and
./secrets.toml.
idp-server <subcommand> [options]
serve Run the server [--config <file>] [--secrets <file>] [--env-file <file>] bootstrap Print or purge generated one-time secrets get [--format raw|json|env] [--kind <k>] [--id <i>] [--field <f>] purge [--kind <k>] [--id <i>] [--config <file>] [--secrets <file>] generate-config Write a documented configuration template --output <file> [--force] validate-config Validate configuration (and optional secrets) --config <file> [--secrets <file>] config check Load as serve would, environment included; validate offline [--config <file>] [--secrets <file>] [--print] generate-enc-key Print a fresh 32-byte encryption key (base64) [--with-key-id <identifier>] generate-secrets Write a fresh secrets file --output <file> [--force] hash-password Hash a password from stdin and print the Argon2id hash [--m-cost <kib>] [--t-cost <n>] [--p-cost <n>] (defaults 19456/2/1, the OWASP parameters; the memory floor is 19456 KiB)When no configuration file exists, a built-in default configuration is used
(localhost:8080, HTTP, embedded storage in ./data) and a warning is
logged. Unknown keys in a real configuration file are fatal.
First login (bootstrap administrator)
Section titled “First login (bootstrap administrator)”On first start the initial administrator account is seeded. The address and password come from the bootstrap environment overrides:
| Variable | Purpose |
|---|---|
GUARD_BOOTSTRAP_ADMIN_EMAIL |
Administrator email address |
GUARD_BOOTSTRAP_ADMIN_PASSWORD_ARGON2ID |
Pre-hashed Argon2id password |
GUARD_BOOTSTRAP_ADMIN_PASSWORD_PLAIN |
Plain-text password (hashed on boot) |
When no password is provided, a random one is generated and printed once
to the server log. First-boot seeding is detected by an empty signing-key
table. The admin-console relying party registers itself automatically on
boot.
Origins matter. On first boot with console serving enabled, the server
registers the admin-console relying party with the issuer origin as its
redirect URI. Browsers must reach the console on exactly the configured
server.public_url host (http://localhost:8080, not 127.0.0.1:8080) —
the authorization redirect match is strict by design.
Next steps
Section titled “Next steps”For configuration, secrets, storage, TLS, and upgrades, see Deployment; for Kubernetes, see the Helm chart; for every configuration key, see the Configuration reference.