Configuration, credentials, cache, and state locations

Updated Aug 08, 2026

Concordat's local configuration, credentials, caches, and state live under the XDG base directories. A single global headline file names the active configured owner; per-owner configuration, credentials, estate caches, and state are namespaced beneath that owner, while the OpenTofu provider plugin cache is shared across owners, since provider binaries are identical regardless of owner:

  • $XDG_CONFIG_HOME/concordat/config.yaml — the headline config, global rather than owner-namespaced; its github_owner key names the active owner. Manage it with concordat owner use <owner> and inspect it with concordat owner show.
  • $XDG_CONFIG_HOME/concordat/owners/<owner>/config.yaml — that owner's estates and active estate.
  • $XDG_CONFIG_HOME/concordat/owners/<owner>/credentials.yaml — optional credential fallbacks, mapping credential environment-variable names (GITHUB_TOKEN, SCW_ACCESS_KEY, SCW_SECRET_KEY, AWS_*, SPACES_*) to values. Environment variables always win. The file must be chmod 600: concordat refuses to read one carrying any group or world permission bit. Concordat never writes this file.
  • $XDG_CACHE_HOME/concordat/owners/<owner>/estates/<alias> — estate repository caches.
  • $XDG_CACHE_HOME/concordat/tofu/plugin-cache — the shared OpenTofu provider plugin cache (exported as TF_PLUGIN_CACHE_DIR unless already set).
  • $XDG_STATE_HOME/concordat/owners/<owner>/runs/ — throwaway OpenTofu working trees; removed after each run unless --keep-workdir is given.

Remote OpenTofu state stored in the configured S3 backend (for example Scaleway Object Storage) is unaffected by this layout.

Migration from the legacy flat format. Older releases wrote estates directly into $XDG_CONFIG_HOME/concordat/config.yaml — the same path the headline config now occupies. A file found there carrying an estate section is therefore a legacy configuration: its estates are moved into owners/<owner>/config.yaml automatically the first time the owner can be derived from those records, and the headline file is rewritten with only its github_owner key and any other non-estate settings.