Aion GitHub deployment variables
Composer can store an Aion GitHub deployment variable as a literal or a protected value. Protected values are encrypted at rest and cannot be displayed after they are saved. During deployment, Aion securely installs them into the container environment. Inside the container, protected values are available as ordinary environment-variable strings. Application code and logging tools can read them, so do not log or persist sensitive environment variables. Composer cannot reveal or copy a protected value. Converting one to literal starts with an empty value. Converting a literal to protected requires entering the value again. Aion does not install deployment environment variables for Aion Remote or A2A Remote. Configure those self-managed process environments through your own infrastructure. Aion supplies these variables to hosted deployments itself, so Composer does not take them as Project deployment variables. In a self-managed runtime, set the ones your deployment needs in your own process environment. The sections below cover those the SDK itself reads.VERSION_IDDEPLOYMENT_IDAION_CLIENT_IDAION_CLIENT_SECRETAION_API_HOSTLOGSTASH_HOSTLOGSTASH_PORT
Aion Control Plane Settings
These settings control optional integration with the Aion control plane. When they are not provided,aion serve can still start local agent and proxy
processes, and you can invoke agents directly through the local A2A and proxy
endpoints with an anonymous session token. Without them, the SDK cannot authenticate with or use the Aion control
plane.
For deployments hosted by Aion, the control plane provides these values
automatically. Set them yourself only when running outside Aion-hosted
deployments or when testing local control plane connectivity.
| Variable | Type | Required | Default |
|---|---|---|---|
AION_CLIENT_ID | string | No | unset |
Client ID used with AION_CLIENT_SECRET for control plane
authentication. For Aion-hosted deployments this is populated by the
Aion control plane. Set it manually only for self-managed deployments
or local testing against the control plane. It is also the audience of
the invocation tokens Aion sends to this runtime: a self-managed server
accepts invocation tokens only when it is set. See
Caller Authentication. | |||
AION_CLIENT_SECRET | string | No | unset |
Secret paired with AION_CLIENT_ID for control plane
authentication. For Aion-hosted deployments this is populated by the
Aion control plane. Set it manually only for self-managed deployments
or local testing against the control plane. | |||
AION_API_HOST | string | No | https://api.aion.to |
Base URL for Aion control plane HTTP and WebSocket calls. Must start
with http:// or https://; invalid values fail
settings validation during startup. The server also loads the public
keys that verify caller tokens from this host, which requires
https:// except for a loopback address. | |||
AION_API_KEEP_ALIVE | integer | No | 60 |
| Keep-alive interval exposed by SDK settings for control plane connections. If unset, the SDK uses the default value. | |||
AION_REQUIRE_INVOCATION_AUTH | boolean | No | false |
When true, a self-managed server accepts only invocation
tokens, that is, only requests Aion routes to it; anonymous session
tokens are refused. Requires AION_CLIENT_ID, or the server
does not start. Aion-hosted deployments always behave this way. See
Caller Authentication. | |||
Storage Settings
| Variable | Type | Required | Default |
|---|---|---|---|
POSTGRES_URL | string | No | unset |
| PostgreSQL DSN for persistence and DB-backed features. If unset, the SDK uses in-memory storage where supported. If set but unreachable, startup fails. | |||
| This database is used for A2A task history and other durable runtime data. Framework adapters can also use it for framework-specific persistence, such as LangGraph execution state and checkpoint data when PostgreSQL-backed checkpointing is enabled. | |||
| In-memory task storage is limited to the life of a single process: a second process serving the same agent shares nothing with the first, and a task that was running when a process died is gone with the store. With this variable set, the server runs a2a-sdk’s cluster mode, and any number of instances of one agent can share the database - see Multiple instances. A deployment that runs more than one instance of an agent needs this variable. | |||
FILE_STORAGE_BACKEND | string | No | unset |
Optional backend for converting inline file parts into URI-based file
references. When unset, file content is left inline. Two values are
accepted: aion uploads to the
Aion File Service and needs
AION_CLIENT_ID and AION_CLIENT_SECRET;
stub is for development and test flows. Any other value
fails startup when file upload handling is initialized. | |||
The server stores inline file bytes before anything persists them and
replaces them with URLs: files in incoming messages, and files the agent
sends in replies and artifacts, ADK artifacts included. A request
carrying a file that cannot be stored is rejected. A file the agent sends
that cannot be stored fails the task: what the agent sent beside it is
still delivered, the run stops, a message/send caller
receives an internal error (-32603) with the reason, and the agent log
keeps a warning for the file.
Agent output uses the protected artifact route. The Aion provider requests
30-day retention when no file action is present. An action with an
omitted or null deadline requests indefinite storage. See
Artifact Builders.
The provider obtains a temporary read-grant URL for
delivery; that URL’s expiry is separate from file retention. See
File Service for permissions and
explicit retention changes. | |||
POSTGRES_POOL_MIN_SIZE | integer | No | 2 |
Connections each pool opens and keeps open. Two pools sit in front of
one PostgreSQL — SQLAlchemy for tasks and ADK, psycopg for the LangGraph
saver — and both are sized from this and the maximum below, so the
connection budget is pods x processes x pools. Applies only when
POSTGRES_URL is set. | |||
POSTGRES_POOL_MAX_SIZE | integer | No | 10 |
Upper bound on concurrent connections. Applies only when
POSTGRES_URL is set. | |||
DB_MIGRATE_ON_START | boolean | No | true |
Whether a server applies the database migrations when it starts. With false it only
checks them and refuses to start while the database is behind: run aion db migrate
before the servers start, and their database user needs no right to change the schema. See
CLI Reference. Applies only when POSTGRES_URL is set. | |||
ENCRYPTION_KEY | string | No | unset |
Fernet keys encrypting sensitive persisted data at rest, such as
push-notification configurations, which carry webhook credentials,
separated by commas. The first key encrypts; every key in the list
decrypts. Each must be a URL-safe base64-encoded 32-byte key; an unusable
value fails settings validation. When unset, that data is stored in
plaintext. Generate a key with
python -c “from cryptography.fernet import Fernet; print(Fernet.generate_key().decode())”.
To rotate the key with several servers running, deploy three values in
turn, each once every server runs the previous one: old,new,
then new,old, then new. Data is not re-encrypted:
keep old in the list while data written with it is still
needed. A push notification configuration whose key has been removed
cannot be read, and its webhook receives nothing. | |||
PUSH_NOTIFICATION_TIMEOUT_SECONDS | float | No | 5.0 |
Seconds the server waits on a webhook while delivering a push
notification: for sending the request and for reading the answer.
Connecting to the webhook is limited to 5 seconds whatever this says.
Deliveries are made one at a time, so a webhook that answers slowly
holds back the run’s later events, on every channel, for up to this
long per delivery. See
Task Updates.
On a server the Aion platform hosts, a webhook
URL must be http or https and resolve to
public addresses only: a config naming a loopback, private or
link-local address is refused, and a delivery to one is skipped. | |||
Task Lifecycle Settings
| Variable | Type | Required | Default |
|---|---|---|---|
AION_SHUTDOWN_TIMEOUT | float | No | 25 |
Seconds an agent server may take to stop. On SIGINT or SIGTERM,
aion serve asks every agent to stop at once and kills an
agent that is still running when this time is spent. The agent stops
accepting requests and divides the time among the steps of its
shutdown, which run one after another. By default: 15 seconds for the
running turns of the toolkit plugins the agent hosts, if any, to stop;
5 seconds for the connections still open, which are then closed;
2 seconds for settling the tasks the shutdown interrupted; 3 seconds
for the rest. Above 25 seconds the extra time goes to the first step;
below it the last three steps shrink in proportion. | |||
A task the server was still running when it stopped is settled as
FAILED with aion:settledReason set to
server_shutdown, and its push notification is sent; a
webhook that has not answered when the settlement’s time is spent is
not waited for. A stream open on such a task is closed before the task
is settled: resubscribe or poll GetTask for the outcome. See
Task Updates. | |||
Set it a few seconds below the stop timeout of the platform running the
server, such as Kubernetes terminationGracePeriodSeconds or
docker stop -t, so the server finishes its own shutdown
first. It must be a positive number; a value below 10 is accepted with
a warning at startup. | |||
AION_STALE_TASK_TIMEOUT | float | No | 3600 |
Seconds a task may stay SUBMITTED or WORKING
without a durable write - a status or an artifact the task stores -
before it counts as abandoned: the server running it died or hung. Such
a task is settled as FAILED with
aion:settledReason set to task_abandoned, and
its push notification is sent. 0 turns the settlement
off. | |||
| Every server of the agent looks for abandoned tasks every minute, or every half timeout when that is shorter, and one server sweeps at a time. A message into an abandoned task settles it first and is then refused as a message into a task with an outcome. A server never settles a task whose turn runs in its own process, and no task waiting for input is settled. A task written while it is being settled keeps its state. Keep the value above the longest time a turn of the agent goes without writing a status or an artifact. See Multiple Instances. | |||
Logging Settings
| Variable | Type | Required | Default |
|---|---|---|---|
LOG_LEVEL | string | No | INFO |
Allowed: DEBUG, INFO, WARNING,
ERROR. Invalid values fail settings validation. | |||
LOGSTASH_HOST | string | No | unset |
Host for centralized log shipping. Must be set together with
LOGSTASH_PORT; otherwise remote log shipping remains
disabled and logs stay on local stream handlers. For Aion-hosted
deployments, the control plane populates this automatically. | |||
LOGSTASH_PORT | integer | No | unset |
Port for centralized log shipping. Must be set together with
LOGSTASH_HOST; otherwise remote log shipping remains
disabled. For Aion-hosted deployments, the control plane populates this
automatically. | |||
VERSION_ID | string | No | unset |
Optional deployment version identifier used primarily in log and
deployment metadata. For Aion-hosted deployments, the control plane
populates this automatically. If set, the SDK uses this value directly.
If unset, aion serve attempts to fetch it from the control
plane; on failure it logs a warning and continues without a version ID. | |||
Miscellaneous Settings
| Variable | Type | Required | Default |
|---|---|---|---|
AION_DOCS_URL | string | No | https://docs.aion.to |
| Base documentation URL used when the SDK builds agent-card extension links. If unset, the default docs URL is used. | |||
Loading Behavior
- Variables can be provided through the system environment or a
.envfile in the project root. - If the same variable is set in both places, the system environment value wins.
- Variable names are case-insensitive in settings parsing.
- Missing optional variables use defaults or remain unset.
- Variables with explicit format or allowed-value constraints fail validation when set to invalid values.