Skip to content

Getting started ​

Armite is a single Go program, with Azurite beside it for storage accounts. Three ways to run it:

bash
# The image: Azurite inside, nothing to install (see Running in Docker)
docker run -d --name armite -p 127.0.0.1:8443:8443 -p 127.0.0.1:8081:8081 \
  -v armite:/data ghcr.io/ioflux-org/armite

# A binary: Go 1.26, or the archive for your platform from the releases page
go install github.com/ioflux-org/armite/cmd/armite@latest && armite

# A clone
git clone https://github.com/ioflux-org/armite && cd armite && go run ./cmd/armite

Release archives for Linux, macOS and Windows, with checksums, are at github.com/ioflux-org/armite/releases; armite version prints the version you have.

The server generates a private CA in ~/.armite/ at first boot, keeps what you create in your data directory (~/.local/share/armite on Linux), and serves https://management.localhost:8443 (ARM), https://login.localhost:8443 (Entra), https://{vault}.vault.localhost:8443 (Key Vault data plane) and https://{account}.blob.core.localhost:8443 (blobs), plus IMDS on http://127.0.0.1:8081. Storage accounts need azurite-blob on your PATH (npm install -g azurite; the Docker image has it) and are otherwise off. See Running in Docker for the container route.

Two things every client needs:

  1. Hostnames resolving to 127.0.0.1. Linux with systemd-resolved does it already; WSL2 and macOS need a one-time resolver fix or the /etc/hosts lines armite hosts prints — see Hostnames.
  2. The CA. ~/.armite/ca.pem, passed per client (curl --cacert, REQUESTS_CA_BUNDLE, NODE_EXTRA_CA_CERTS, SSL_CERT_FILE).

The demo ​

The Azure CLI, in a config directory of its own so your real Azure login is untouched:

bash
export AZURE_CONFIG_DIR=$HOME/.azure-armite REQUESTS_CA_BUNDLE=$HOME/.armite/ca.pem
az cloud set -n AzureCloud 2>/dev/null; az cloud unregister -n Armite 2>/dev/null
az cloud register -n Armite --endpoint-resource-manager https://management.localhost:8443
az cloud set -n Armite
az config set core.instance_discovery=false
az login --service-principal -u 33333333-3333-3333-3333-333333333333 \
  -p armite-secret --tenant 11111111-1111-1111-1111-111111111111

az group create -n kv-rg -l eastus
az keyvault create -n kv-demo -g kv-rg -l eastus --enable-rbac-authorization
az keyvault secret set --vault-name kv-demo -n db-pass --value hunter2   # 403
az role assignment create --role "Key Vault Secrets Officer" \
  --assignee-object-id 44444444-4444-4444-4444-444444444444 \
  --assignee-principal-type ServicePrincipal \
  --scope $(az keyvault show -n kv-demo -g kv-rg --query id -o tsv)
az keyvault secret set --vault-name kv-demo -n db-pass --value hunter2   # 200

The same demo through the SDK is scripts/sdk-smoke/keyvault-smoke.mjs, and through Terraform examples/terraform. The storage twin — Owner creates a container and cannot upload a blob — is in Storage accounts and blobs. Client setup for every tool is in Client setup.

Built-in identities ​

Armite is one tenant with one subscription and two principals, all fixed and documented, so nothing needs registering:

value
Tenant11111111-1111-1111-1111-111111111111
Subscription22222222-2222-2222-2222-222222222222
Service principal (Owner of the subscription)client 33333333-3333-3333-3333-333333333333, secret armite-secret, object 44444444-4444-4444-4444-444444444444
Managed identity (Contributor of the subscription)client 55555555-5555-5555-5555-555555555555, object 66666666-6666-6666-6666-666666666666, via IMDS

The managed identity is the one your production code path uses: DefaultAzureCredential with AZURE_POD_IDENTITY_AUTHORITY_HOST=http://127.0.0.1:8081 and no secret anywhere, exactly as on a VM, and its roles are enforced.

Released under the Apache License 2.0. Azure, Entra and Key Vault are Microsoft trademarks; Armite is not affiliated with or endorsed by Microsoft.