This guide walks through setting up Infisical as the secret manager
for Axion, migrating existing secrets from config.yaml, and verifying
the integration.
Run the start script from the project root:
./resource.bin/start_infisical.sh
This starts three containers:
infisical_axion - Infisical web app (port 8480)infisical_db_axion - PostgreSQL databaseinfisical_redis_axion - Redis cacheWait for all containers to become healthy:
docker compose -f resource.docker/resource.compose/infisical-compose.yml ps
http://localhost:8480 in a browserMachine Identities are service accounts for programmatic access.
Then grant the identity access to your project:
Add the infisical section under base:
base:
infisical:
enabled: true
host: http://localhost:8480
client_id: <paste-client-id>
client_secret: <paste-client-secret>
Alternatively, provide credentials via environment variables
(these take priority over config.yaml):
export AXION_INFISICAL_CLIENT_ID=<paste-client-id>
export AXION_INFISICAL_CLIENT_SECRET=<paste-client-secret>
No project_id or environment is needed. Both are derived
automatically from existing config values:
project slug = {package}_{role}_{deployment}
environment = {deployment}
Using system.role and system.deployment from config.yaml.
Examples:
| package | system.role | system.deployment | project slug |
|---|---|---|---|
| homechoice | ao | uat | homechoice_ao_uat |
| homechoice | ao | live | homechoice_ao_live |
| fullhouse | ao | live | fullhouse_ao_live |
| homechoice | collections | uat | homechoice_collections_uat |
Create matching projects in Infisical with these names.
Preview what will be migrated:
python factory.deploy/ObjSecretMigrate.py migrate --dry-run
Run the migration:
python factory.deploy/ObjSecretMigrate.py migrate
This reads all credential sections from config.yaml and creates
corresponding secrets in Infisical using the naming convention
SECTION__OPTION (e.g., DATABASE__PRIMARYIP).
Preview which PEM keys will be uploaded:
python factory.deploy/ObjSecretMigrate.py push-keys --dry-run
Push all PEM keys:
python factory.deploy/ObjSecretMigrate.py push-keys
Once keys are in Infisical, ObjEncryption will use them
automatically. The local files can be kept as fallback or removed
from non-production machines.
Seed the local encrypted cache so secrets are available if
Infisical goes offline:
python factory.deploy/ObjSecretMigrate.py cache-seed
This writes all secrets to data.config/.infisical_cache.yaml,
encrypted with the reference package key. Re-run periodically
or after secret changes.
Compare Infisical values against config.yaml:
python factory.deploy/ObjSecretMigrate.py verify
List all secrets in the project:
python factory.deploy/ObjSecretMigrate.py list
When ConfigIni.Get(section, option) is called:
SECTION__OPTIONdata.config/.infisical_cache.yaml)config.yaml path Infisical secret name
----------------------- ----------------------
base.database.primaryip DATABASE__PRIMARYIP
base.mqtt.password MQTT__PASSWORD
base.aws.secret AWS__SECRET
base.ai_mcp_openai.key AI_MCP_OPENAI__KEY
Double underscore (__) separates section from option.
PEM encryption keys:
data.config/homechoice_private.pem PEM__HOMECHOICE_PRIVATE
data.config/homechoice_public.pem PEM__HOMECHOICE_PUBLIC
Secrets fetched from Infisical are cached for 3600 seconds (1 hour)
to reduce API calls. The cache is per-process and resets on restart.
If Infisical is unreachable (network error, service down), ConfigIni:
The system remains fully operational. The preflight check also
validates PEM keys by reporting their source (cache, infisical,
or file) and running a round-trip encrypt/decrypt test.
To copy secrets between deployment tiers (e.g. UAT to LIVE):
python factory.deploy/ObjSecretMigrate.py promote uat live --dry-run
python factory.deploy/ObjSecretMigrate.py promote uat live
PEM keys are excluded by default. Use --include-pem to include
them.
python factory.deploy/ObjSecretMigrate.py delete DATABASE__PRIMARYIP
python factory.deploy/ObjSecretMigrate.py delete all --force
For production, run Infisical on a dedicated server:
resource.docker/resource.compose/infisical-compose.ymldocker compose up -d to startbase.infisical.host in config.yaml to point to thesystem.deployment is set correctly (e.g. live) -The terraform.infisical section in config.yaml stores the Docker
infrastructure credentials (database password, encryption key, auth
secret). These are used by start_infisical.sh to bootstrap the
containers and are separate from the base.infisical section which
configures the SDK client connection.
Check container logs:
docker logs infisical_axion
docker logs infisical_db_axion
enabled: true in config.yamlSECTION__OPTION, uppercase)system.deployment valueuat, live, sim)