Configuration
Configure one or more named tenants in desktop Settings, or use the CLI. One tenant is active at a time. All tenants share one SQLite database; their history, comparisons and pruning remain isolated by Azure tenant ID.
Create a read-only service principal
Create a service principal with Reader on each subscription to be collected, or on a management group whose subscriptions should be covered:
az ad sp create-for-rbac --name azdocs-reader --role Reader \
--scopes /subscriptions/<subscription-id>
The command returns tenant, appId and password. Enter these as directory
ID, application ID and new client secret. azdocs makes read-only requests, but
the credential itself may have other grants. Permission diagnostics
warn about broader grants and incomplete coverage; a role name alone is not proof.
Create or load a configuration
azdocs init
azdocs config validate
azdocs --tenant default check
init creates the profile reference default. The acme reference used in
the version 2 example below exists only after you create that profile.
The desktop has a first-run path through Settings → Add tenant → Test connection → Save changes, followed by Collect snapshot. A connection test uses the draft and does not save the file. See Desktop.
init writes the platform config file. Search order is --config <path> →
./azdocs.toml → platform config directory. --db <path> overrides the database
for that CLI invocation. Relative file paths in configuration resolve beside
the config file, including database, logo and font directory paths.
| OS | Config file | Default database |
|---|---|---|
| macOS | ~/Library/Application Support/azdocs/azdocs.toml | ~/Library/Application Support/azdocs/azdocs.db |
| Linux | ~/.config/azdocs/azdocs.toml | ~/.local/share/azdocs/azdocs.db |
| Windows | %APPDATA%\azdocs\config\azdocs.toml | %APPDATA%\azdocs\data\azdocs.db |
Version 2 format
schema_version = 2
default_tenant = "acme"
[tenants.acme]
name = "Acme"
tenant_id = "11111111-1111-4111-8111-111111111111"
client_id = "22222222-2222-4222-8222-222222222222"
secret_env = "AZDOCS_ACME_SECRET"
# Desktop/CLI secret entry replaces secret_env with an opaque secret_ref.
[tenants.northwind]
name = "Northwind Traders"
tenant_id = "33333333-3333-4333-8333-333333333333"
client_id = "44444444-4444-4444-8444-444444444444"
secret_env = "AZDOCS_NORTHWIND_SECRET"
[tenants.northwind.audit]
required_tags = []
[tenants.northwind.branding]
company = "Northwind Traders"
[collect]
subscriptions = []
concurrency = 4
[collect.retry]
max_attempts = 5 # per request, 1–10
base_delay_ms = 500 # first backoff; doubles per attempt
max_delay_secs = 60 # ceiling for any wait, including Retry-After
timeout_secs = 120 # whole-request timeout
connect_timeout_secs = 15
[audit]
required_tags = ["environment", "owner"]
[storage]
db_path = "azdocs.db"
[branding]
company = ""
title = "Azure Estate Report"
subtitle = ""
primary_color = "#0078d4"
accent_color = "#4da3e8"
page_size = "a4"
margin = "2cm"
footer = "Generated by azdocs."
theme = "azure"
labels = "en"
# logo = "logo.png"
# font_dir = "fonts/"
# font_family = "Acme Grotesk"
# mono_family = "Acme Mono"
[report]
max_group_diagrams = 60
max_figure_nodes = 6
max_evidence_rows = 20
Profile references use letters, digits, underscores or hyphens. Directory and application IDs must be UUIDs. Each tenant ID has one profile. Unknown keys, invalid colours, concurrency outside 1–64 and retry attempts outside 1–10 fail validation.
Sovereign clouds
cloud selects the Azure environment and may be set as a shared default at
the top of the file or per tenant:
cloud = "public" # default
[tenants.federal]
name = "Federal"
tenant_id = "55555555-5555-4555-8555-555555555555"
client_id = "66666666-6666-4666-8666-666666666666"
secret_env = "AZDOCS_FEDERAL_SECRET"
cloud = "usgov"
| Value | Sign-in authority | Management endpoint |
|---|---|---|
public | login.microsoftonline.com | management.azure.com |
usgov | login.microsoftonline.us | management.usgovcloudapi.net |
china | login.chinacloudapi.cn | management.chinacloudapi.cn |
The service principal must exist in that cloud’s Entra tenant. Resource Graph, the RBAC diagnostics and the desktop’s website management calls all follow the same setting; the desktop exposes it under Settings → Collection.
Retries and timeouts
Every request to Entra, Resource Graph and ARM shares [collect.retry].
Transport failures (connection reset, timeout), HTTP 5xx and 429 are retried
with exponential backoff and jitter up to max_attempts; a server’s
Retry-After is honoured but capped at max_delay_secs. A 4xx from the token
endpoint or Resource Graph is a real answer and is never retried. A query that
exhausts its attempts is recorded as failed with the last error, and the
snapshot becomes partial. Tenant profiles may override the block.
Shared [collect], [audit] and [branding] values are defaults. Tenant
sections override only the fields they name. Lists replace inherited lists;
required_tags = [] disables required-tag checks for that tenant, and
subscriptions = [] means all subscriptions visible to its credential.
An omitted field inherits. Storage is always shared. In Settings, clear an
Overridden checkbox to restore inheritance. Empty logo/font-directory
overrides clear the inherited path.
Report limits
[report] sets how much the printed formats show before pointing at the data
exports. max_evidence_rows caps every evidence, change and website table in
the PDF, DOCX, Markdown and HTML; max_figure_nodes is the number of boxes an
assessment figure holds before a relationship family is split across pages;
max_group_diagrams is how many resource groups the technical reference draws
individually. Each value must be at least 1. Every cap is stated in the
output where it applies, and the CSV and XLSX exports are never capped.
Tenant selection
CLI selection is --tenant <reference-or-tenant-id>, then default_tenant,
then the sole profile. Multiple profiles without a default require selection.
Selection also applies to history, latest, reports, diagrams, TUI and pruning.
Explicit snapshot IDs work offline without credentials. With an explicit
--tenant, a snapshot belonging to another tenant is rejected.
The desktop remembers its selected config and tenant locally. Selecting a profile in the editor does not switch the active estate. Use the toolbar’s Tenant selector to switch; search, navigation and snapshot selection reset. Renaming or removing a profile keeps stored history. Unconfigured tenants can still be selected by tenant ID and their reports use shared branding defaults.
Credentials and environment variables
New desktop secrets and interactive init secrets are stored through keyring’s
native store: macOS Keychain, Windows Credential Manager or Linux Secret
Service. The TOML contains only an opaque secret_ref. A locked or unavailable
store produces an error; there is no plaintext fallback. Offline browsing,
validation and reporting do not unlock or read the credential store.
azdocs --tenant acme config set-secret
# For automation, pipe a secret from your secret manager:
secret-manager-command | azdocs --tenant acme config set-secret --stdin
For headless operation, use an explicit secret_env per profile. The named
environment variable supplies only the secret. Global AZDOCS_TENANT_ID,
AZDOCS_CLIENT_ID and AZDOCS_CLIENT_SECRET do not override named profiles;
secret_env = "AZDOCS_CLIENT_SECRET" must be stated explicitly to use that
variable. Environment values are never written back by Settings.
Legacy [auth] and environment-only operation remain supported. In that mode,
nonempty global environment values override the corresponding legacy values:
export AZDOCS_TENANT_ID=...
export AZDOCS_CLIENT_ID=...
export AZDOCS_CLIENT_SECRET=...
azdocs check
Migrate a legacy file
Use the migration action in Settings, or:
azdocs config migrate --reference acme --name "Acme"
Migration preserves file identity and shared defaults, verifies each stored
file secret, creates a protected azdocs.toml.backup-<uuid> beside the original,
and atomically replaces plaintext credentials with references. Environment
secrets stay in the environment. If the legacy file omits identity fields,
create a profile with explicit IDs in Settings instead of migrating it.
The previous file remains intact when validation, credential verification or
file replacement fails. Backups of legacy files contain the original secret;
keep them protected and delete them when rollback is no longer needed. Old
native references remain available to backups and copied configurations.
Save, validate and diagnose
azdocs config show # redacted JSON: configured + resolved
azdocs --tenant acme config validate
config show and the desktop diagnostic export exclude secret values. Settings
saves preserve TOML comments, use protected temporary files and atomic
replacement, and reject stale revisions if another process edited the file.
Reload an externally edited file before making a new save. Settings remains
accessible with a missing or invalid file; errors omit potentially sensitive
source lines. Application selects or reloads a configuration and opens a
chosen database without moving existing files.
Branding
The [branding] section themes every styled report format — the HTML report
and docs site, the PDF, the DOCX and the XLSX. Every field is optional; the
defaults reproduce the stock look. Colors must be six-digit #rrggbb values,
and the logo may be a .png, .jpg, .gif, or .svg file.
theme selects a document theme: colours, type scale and layout
strategies, all defined in TOML rather than code. azure (the default) carries
the desktop design language into print; field-report is the quieter
paper-and-ink alternative. You can add an organisation
theme under <config dir>/azdocs/themes/; brand colours stay reserved for
identity, links and signals rather than document chrome. See
reference/themes.md.
labels selects the wording: every heading, column header, caption and
message azdocs prints, again TOML rather than code. en is the only built-in.
A partial file under <config dir>/azdocs/labels/ changes just the keys it
names. See reference/labels.md.
page_size and margin apply to the PDF and the DOCX. Word only knows the
common paper sizes (A3/A4/A5, US Letter/Legal/Tabloid); anything else logs a
warning and falls back to A4 in the DOCX while the PDF still honours it.
Fonts
Field Report prefers installed Charter, Arial and Courier New for PDF and
Word. PDF falls back to the bundled IBM Plex families when these faces are
unavailable; font resolution stays offline. Point font_dir at a
directory of .ttf/.otf files and set font_family/mono_family to replace
the working faces.
The DOCX cannot do this: OOXML names a font and Word resolves it on the
reader’s machine, and azdocs cannot embed fonts into a .docx. The shipped
theme therefore asks Word for Charter, Arial and Courier New. Older Office
installs substitute their configured defaults. Override docx_serif,
docx_sans and docx_mono in a theme file if your organisation deploys its
own typefaces.
Next: Collecting