NAME

skeid - Skeid control-plane CLI and proxy launcher

VERSION

version 0.003

SYNOPSIS

skeid serve [--listen host:port] [--config skeid.yaml] [--admin-api-key KEY] [--workers N]
skeid usage [--config skeid.yaml] [--since ISO8601] [--limit N] [--json]
            [--backend jsonlog|sqlite|postgresql] [--log-path /path/to/events/]
            [--db /path/to.sqlite] [--dsn dbi:Pg:...]
            [--db-user USER] [--db-pass PASS | --db-pass-env VAR]
            [--api-key-id ID] [--model NAME]
skeid keyid [KEY ...]

DESCRIPTION

Runs the Skeid proxy (Langertha::Skeid::Proxy), reports recorded usage, and prints the customer key id a key routes and bills under. With no command, or when the first argument is an option, the command is serve. An unknown command prints the usage text and exits non-zero.

The config file is described in "CONFIGURATION" in Langertha::Skeid.

COMMANDS

serve

skeid serve --config /etc/skeid/skeid.yaml --listen 0.0.0.0:8090 --workers 4

Builds the app with "build_app" in Langertha::Skeid::Proxy and serves it -- with Mojo::Server::Daemon, or Mojo::Server::Prefork when --workers is above 1. Prints the address and config it starts with, and warns for every node whose max_conns cannot be split across the workers and frontends ("worker_share_warnings" in Langertha::Skeid).

--listen, -l

host:port to listen on (default 127.0.0.1:8090).

--config, -c

The YAML config. A path given here that is not an existing file ends the command with ERROR: config file not found: ... on standard error and exit code 2 -- Skeid does not start without the config it was told to use. Without --config, skeid.yaml in the working directory is used when it exists; when it does not, Skeid starts without a config, with no nodes (the admin API can add them). A config file that disappears while Skeid runs keeps the config in force and is warned about once ("maybe_reload_config" in Langertha::Skeid).

--admin-api-key

Admin API key. It wins over any key the config names, on every reload; without it the key comes from the config, else from SKEID_ADMIN_API_KEY (see "admin" in Langertha::Skeid). A key on the command line is visible in the process list, so in production prefer admin.api_key_env in the config.

--workers, -w

Prefork worker count (default 1; below 1 counts as 1). Each worker admits its share of every node's max_conns and polls capacity probes at its share of the rate (ADR 0010). Under several workers a SQLite usage store is unsafe, and an admin API write reaches only the worker that served it.

A usage store with flush_interval_ms holds events in memory until they are written; stopping the server writes them. Stop a prefork server with SIGQUIT (graceful): on SIGINT or SIGTERM Mojolicious's prefork manager kills its workers with SIGKILL, and what they still held is lost. A single process (--workers 1) flushes on SIGINT, SIGTERM and SIGQUIT.

usage

skeid usage --config /etc/skeid/skeid.yaml --since 2026-09-01T00:00:00Z --limit 50

Prints a usage report: the backend and store (a jsonlog path, the SQLite file, or configured DSN), totals, per API key id, per model, and the newest events. The store is the config's usage_store; any of --backend, --log-path, --db, --dsn, --db-user, --db-pass or --db-pass-env replaces it with a store built from those options alone. Exits 0, or 2 after printing ERROR: ... when the report fails (no store configured, say) or --config names no file.

--config, -c

As for serve: a missing file is an error; without the option, skeid.yaml is read when it exists.

--since

Only events with created_at at or after this ISO 8601 UTC timestamp.

--limit

How many recent events to list (default 20, at most 500; below 1 means 20).

--json

Print the report as JSON instead of the text summary.

--backend

jsonlog, sqlite or postgresql. Implied by --log-path, --db or --dsn.

--log-path, --jsonlog

A jsonlog store: its event directory (one file per event) or its JSON-lines file. An existing directory, or a path ending in /, is read as a directory; anything else as a file.

--db, --sqlite

SQLite database file.

--dsn

PostgreSQL DSN, dbi:Pg:....

--db-user, --db-pass

PostgreSQL credentials. A password on the command line lands in the shell history; prefer --db-pass-env.

--db-pass-env

Name of an environment variable holding the PostgreSQL password.

--api-key-id

Only events of this customer key id.

--model

Only events for this served model.

keyid

echo -n "$CUSTOMER_KEY" | skeid keyid
skeid keyid sk-alice-secret

Prints the customer key id ("key_id_for_key" in Langertha::Skeid) of each key given, one per line -- the id a config's keys: and names: sections use, so the config never holds the key. Without arguments it reads one key per line from standard input, which keeps the key out of the shell history. With no key at all it prints the usage text and exits non-zero.

ENVIRONMENT

serve and usage build a Langertha::Skeid, which reads SKEID_ROUTE_WAIT_TIMEOUT_MS, SKEID_ROUTE_WAIT_POLL_MS, SKEID_TRUST_KEY_ID_HEADER, SKEID_FRONTEND_COUNT, SKEID_ADMIN_API_KEY, SKEID_USAGE_DB, SKEID_CAPACITY_MAX_AGE_MS and SKEID_CONFIG_RELOAD_INTERVAL ("ENVIRONMENT" in Langertha::Skeid), and whatever variables the config names. serve also reads:

OPENBAO_ROLE_ID, OPENBAO_SECRET_ID

Both set: upstream keys (api_key_ref) are resolved from OpenBao through AppRole.

OPENBAO_ADDR

The OpenBao address (default http://127.0.0.1:8200).

OPENBAO_VERIFY_SSL

0, false, no or off disables TLS verification towards OpenBao -- for a dev vault only.

SKEID_UPSTREAM_POOL

Upstream connections kept per process (default 100).

SKEID_UPSTREAM_TIMEOUT

Seconds an upstream request may take, and may be silent for (default 300; a positive integer). The client's connection is kept open for as long on top of the server's own inactivity timeout, on the routes that call an upstream -- see "build_app" in Langertha::Skeid::Proxy.

SEE ALSO

Langertha::Skeid, Langertha::Skeid::Proxy

SUPPORT

Issues

Please report bugs and feature requests on GitHub at https://github.com/Getty/langertha-skeid/issues.

IRC

Join #langertha on irc.perl.org or message Getty directly.

CONTRIBUTING

Contributions are welcome! Please fork the repository and submit a pull request.

AUTHOR

Torsten Raudssus <torsten@raudssus.de> https://raudssus.de/

COPYRIGHT AND LICENSE

This software is copyright (c) 2026 by Torsten Raudssus.

This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself.