Skip to content

Configuration

Everything is configured through the environment — .env next to the compose file — and read by core/app/config.py and by each kit's config.py. Nothing is configured in code.

AG_SECRET_KEY: losing it means every stored secret is unreadable

Database passwords, SSH keys and every other secret are encrypted at rest with this key. There is no recovery path without it. Replacing the key without re-encrypting does not break the core: it shows such secrets as "does not open with this key", and every job that needs one of them fails. There is no re-encryption procedure in the platform yet — the repository names this explicitly as not done.

Keep a copy of AG_SECRET_KEY outside the installation, and keep your licence key separately from the installation as well: a rebuilt host with neither is an installation nobody can open and a licence nobody can prove.

What reaches the containers, and what does not

compose.yaml passes variables to each service explicitly, in its environment: block; it has no env_file:. A variable that .env.example lists but the compose file does not pass (for example AG_TICK or AG_PG_COMPRESS) is read by the code, but setting it in .env has no effect until you add it to the service's environment:. The tables below say for each variable whether the compose file passes it.

Set in the interface, not here

Some things are decided once per installation and live on the Configuration screen rather than in this file, because they are read from the database and changed while the platform runs.

The timezone. What a schedule means by "03:00", and when a rota hands over. An IANA name — Europe/Moscow — with today's offset shown beside it; an offset alone is not a timezone, because it does not know when the clocks change. Changing it takes with it every schedule and every team that was still on the previous one: those took it because it was the installation's answer, not because anybody chose it. Anything told something else stays where it is, and the screen says how many will move before you press Save.

A schedule may still name its own, and an offset in that box is refused: UTC+3 is not a zone, and a schedule that carries one runs at a different hour from the one the screen shows.

The environments. What a resource may be marked as. A new installation starts with prod, stage, test and dev, and the list is editable: an estate with preprod or qa says so. Renaming one renames it on every resource that carries it — otherwise one environment would quietly become two, and the old one would appear in the table and in no filter. One that resources still carry cannot be deleted, and the refusal says how many.

The platform's own copy. A pg_dump of this platform's database — the targets, the rules, the schedules, the secrets and the record of every copy ever made — written to a volume of its own on a cadence you set, keeping as many as you say. Free on every level: an installation that had to buy the ability to keep its own configuration is not one anybody should trust with anybody else's.

A copy on this machine survives a mistake, not a fire. Download the newest one and take it somewhere else, and keep AG_SECRET_KEY with it — the secrets inside are encrypted with that key, and a copy without it is a copy of ciphertext. The list says which key each copy opens with, by name.

How deep the history goes. Every measurement the platform and its kits take is kept in three resolutions, each for as long as you say: full detail (days), one row an hour (months), one row a day (years). Older detail is folded into the next resolution rather than deleted, and a summary carries the smallest and largest value it was made from — a mean on its own would hide exactly the spike that made somebody open the graph.

The defaults are two days, ninety days and two years, and the screen shows what the history occupies now and what it will settle at before you change anything. It is worth a look: full detail is what the table is mostly made of, and eight days of it on a modest estate is well over a gigabyte, while two years of daily summaries is a fraction of that.

Required

Variable What it does If not set
AG_SECRET_KEY Key for encrypting secrets at rest (С1.1 in the specification). Generate with openssl rand -base64 32. Passed to core. The core does not start. The compose file refuses with AG_SECRET_KEY must be set.
AG_MODULE_SECRET The one installation secret from which each kit's token is derived, so both sides compute it and it is stored nowhere. Generate with openssl rand -hex 32. Passed to core and to every kit. Nothing starts. The compose file refuses with AG_MODULE_SECRET must be set, and the core and each kit refuse on their own as well, saying how to make one — without it a kit would trust whoever called it first, and the network kit's port is on the LAN.

Signing in

Optional, and the defaults are the ones described on the Security page. The first four are passed by the compose file and read by the core. AG_INSECURE_TRUST_FIRST_CALLER is read by the core and by every kit, and the compose file does not pass it: if you must set it, add it to each service's environment:.

Variable What it does Default
AG_LOGIN_MAX_FAILS Failed sign-ins allowed for one login inside the window, after which the answer is 429 with a Retry-After. 10
AG_LOGIN_MAX_FAILS_ADDRESS The same for one source address. Much larger on purpose: an office behind one NAT is a single address for everybody in it. 100
AG_LOGIN_WINDOW The window, in seconds. It slides — the wait is until the oldest failure in it ages out — and a correct password clears the count. 900
AG_TRUST_PROXY Whether X-Forwarded-For is believed. Set it to 1 behind a reverse proxy, where otherwise every request arrives from the proxy and the whole installation shares one address's budget. Leave it off when there is no proxy: a header anybody can set would let anybody be any address. 0
AG_INSECURE_TRUST_FIRST_CALLER Set to yes to start without AG_MODULE_SECRET, restoring the old behaviour where a kit trusts the first token it is shown. Defensible on one machine where nothing but the core can reach the kits, and nowhere else. unset

First administrator

Variable Default What it does Passed by compose
AG_ADMIN_USER admin Login of the first administrator, created once on an empty installation. yes (core)
AG_ADMIN_PASSWORD (empty) Password of the first administrator. If empty, it is written once to the core's log at first start. yes (core)

Database and ports

Variable Default What it does Passed by compose
AG_DB_NAME adminguide Name of the shared PostgreSQL database. used to build AG_DATABASE_URL and to configure postgres
AG_DB_USER ag Database user. same
AG_DB_PASSWORD ag Database password. The default is ag; set your own. same
AG_DB_PORT 5432 Host port PostgreSQL is published on, loopback only. Change it when the host already runs a PostgreSQL of its own; the Network Map Kit reaches the database through this port because it is on the host network. port mapping of postgres, kit-net
AG_DATABASE_URL built from the three above The connection string the core and every kit actually read. Set by the compose file per service. yes
AG_PORT 8090 Port of the platform's web interface on the host. port mapping of core
AG_IMAGE_REPO adminguide1, set in .env.example The Docker Hub namespace the images are pulled from: adminguide1/ahegao-kit is the core, adminguide1/ahegao-kit-<kit> a kit. Set it to your own namespace after building from source with tools/images.sh. image: of every service
AG_TAG the release version, set in .env.example The image tag every service runs. Pin it to a version; latest moves. The compose file has no fallback for this variable or for AG_IMAGE_REPO: unset, docker compose refuses and names it. image: of every service
AG_ARTIFACTS_DIR /srv/artifacts Where the default storage default · local is created on first start, as seen from inside the core. Only if the directory is visible from the core; the compose file mounts the artifacts volume there. no
AG_NET_PORT 8101 Port of the Network Map Kit. The kit is on the host network, so this is a host port. yes (kit-net)
AG_<KIT>_KIT_PORT — one per kit in the compose file, e.g. AG_PG_KIT_PORT, AG_NEXUS_KIT_PORT 8102 and up Ports of the other kits on the private compose network. Each is handed to its kit as AG_<KIT>_PORT. Must match the address in AG_MODULES. yes
AG_MODULES every kit this release ships (see Quickstart) Which kits are deployed: id=address,id=address. The core contains no kit name of its own — this list is the list of kits. yes (core)
AG_CORE_URL http://core:8090 (kit-net: http://127.0.0.1:8090) Where a kit finds the core. Set by the compose file per kit. yes

Licence

Variable Default What it does Passed by compose
AG_LICENSE_KEY (empty) The licence key. Usually installed through the interface; can be given here. Absent means the free level — nothing phones home. yes (core)
AG_LICENSE_PUBKEY (empty) Public half of the signing pair. In a release build it is baked into config.RELEASE_PUBKEY; the override is for development and is not a security boundary — what forbids swapping it is the licence, not the code. yes (core)

Secrets in HashiCorp Vault (optional)

Without these, secrets live in the platform's own store and are opened with the installation key — the default, and it works with nothing else deployed. With them, a secret can be a pointer into Vault: the row holds a path, the value is read at the moment of use and not cached, so a rotation in Vault takes effect from the next job.

Variable Default (compose) What it does
AG_VAULT_ADDR (empty) — secrets stay in the platform's own store Vault address.
AG_VAULT_TOKEN (empty) A plain token. A development arrangement; not a production one.
AG_VAULT_ROLE_ID, AG_VAULT_SECRET_ID (empty) AppRole credentials — what production should use: an eternal token is exactly what Vault exists to avoid.
AG_VAULT_CA (empty) Your own certificate authority, if it is your own. 0 disables verification and says so at every start.
AG_VAULT_NAMESPACE (empty) Vault Enterprise only.

Any of the Vault credentials can be given through a file instead: AG_VAULT_TOKEN_FILE, and the same _FILE spelling for the others. A secret in an environment variable is a secret in docker inspect.

A Vault that is down does not stop the platform from starting: secrets kept locally still open, and pointers say why they cannot.

Network Map Kit

Variable Default What it does Passed by compose
AG_NET_PROFILE polite Traffic budget: polite, normal, fast. polite by default on purpose. yes
AG_NET_ALLOW_PUBLIC 0 Refuse to scan anything outside RFC 1918 unless 1. yes
AG_NET_MAX_TARGETS 8192 Hard ceiling on targets per scan, which no profile can exceed. no — read by the kit, not passed by the compose file
AG_NET_MAX_SOCKETS 768 Hard ceiling on concurrent sockets. no
AG_NET_PROBE_PORTS 33 ports (shells, web, databases, caches, brokers, cluster services) The TCP ports knocked on during discovery for addresses that answered neither ICMP nor ARP. Also settable per run in the interface. no

PostgreSQL Kit

Variable Default What it does Passed by compose
AG_PG_RATE_MIB 0 (no limit) Ceiling on dump read rate, MiB/s. For a database somebody is using, set a number: a backup that takes production down gets switched off together with the backups. yes
AG_PG_COMPRESS 6 Whether the stream is compressed: 0 — no, anything above — yes. no
AG_PG_DUMP_TIMEOUT 21600 (6 h) How long to wait for one dump, in seconds. A hung backup is worse than a failed one: the failed one reports itself. no

The kit reads more knobs than .env.example lists — AG_PG_CONNECT_TIMEOUT, AG_PG_BINDIR, AG_PG_SSLMODE (default require) — in kits/postgresql/app/config.py. The same is true of every other kit; the authoritative list for a kit is its app/config.py.

Other

Variable Default What it does Passed by compose
AG_TICK 15 How often, in seconds, the platform looks at its schedules and cleans up after dead executors. no
AG_POLL 3 How often, in seconds, a kit asks the core for work. no
AG_METRICS_EVERY 60 How often the core measures what it depends on: the database, storages, kits, agents, its own queue. Separate from AG_TICK because none of that changes every fifteen seconds. no
AG_LOG_LEVEL info Log level of the core and kits. yes
AG_SECURE_COOKIES 0 Set to 1 only behind HTTPS: otherwise the browser will not return the session cookie. yes (core)
AG_PUBLIC_URL http://localhost:<AG_PORT> The address the platform is visible at from outside. Used for links inside messages: an "acknowledge" link pointing at http://core:8090 is useless to somebody reading it on a phone. yes (core)
AG_SESSION_TTL 2592000 (30 days) Session lifetime in seconds. Read by the core; not in .env.example. no

Storage paths inside containers

Not environment variables, but part of the deployment contract:

Path Where What
/srv/artifacts core and every kit that writes copies The artifacts volume: where copies are written by kits and measured by the core. One volume, two mounts.