m2-market/docs/config.md

6.2 KiB

m2-market configuration reference

Covers the CLI's local config/state files (per machine/operator) and the m2-ledger service's environment variables. Sourced from specs/001-market-first-wedge/contracts/cli.md, specs/001-market-first-wedge/contracts/ledger-api.md, and specs/001-market-first-wedge/data-model.md (§Operator, §InstallState).

1. ~/.m2-market/config.toml

Per-machine CLI config (contracts/cli.md). One file per operator/machine — operator_id and API keys are provisioned per machine, not shared (data-model.md §Operator: "CLI config carries operator_id + API keys per machine").

# ~/.m2-market/config.toml
# Required: identifies this machine/operator for all ledger + catalog calls.
operator_id = "op_nasr"

# Required: tenant scope for catalog search/index filtering.
tenant = "machine-machine"

# m2-ledger HTTP API (contracts/ledger-api.md). CLI uses a "service"-class key
# (see §4 below) — never an admin key.
ledger_url = "http://m2-ledger:8000"
ledger_api_key = "svc_xxxxxxxxxxxxxxxxxxxx"

# Catalog semantic search / indexer backend.
memory_api_url = "https://memory.machinemachine.ai"
memory_api_key = "mem_xxxxxxxxxxxxxxxxxxxx"

# Registry (Forgejo) — used by `m2-market publish` to push branches/open listing PRs.
forgejo_url = "https://git.machinemachine.ai"
forgejo_token = "frg_xxxxxxxxxxxxxxxxxxxx"

# Which AdapterProtocol implementation `install` uses to plan/apply/verify bundles
# (contracts/apply-adapter.md). "local" is the only adapter in v1.
apply_adapter = "local"

Notes:

  • All four *_url + *_key/*_token pairs are required for install/publish/search to function; wallet/show need at least ledger_url+ledger_api_key.
  • File permissions must be 0600 — this file holds live API keys. Treat it the same as an SSH private key (see §5 Security rules).
  • No secrets are ever baked into images or repos; this file is the runtime injection point (constitution VI).

2. ~/.m2-market/state.json

Per-machine install ledger for the local AdapterProtocol — the idempotency and re-apply guard install checks before re-running work (Story 1 AC-3: re-run with an existing grant + applied state is a no-op, exit 0). Shape defined in data-model.md §InstallState; this is the file m2core_sync will merge into once fedlearn rails land.

Shape: {installs: {listing_id: {version, grant_id, ts, changeset_hash, status}}}, where status is one of applied | failed | rolled_back.

Example:

{
  "installs": {
    "sol_pdf_export_v1": {
      "version": "1.2.0",
      "grant_id": "grant_8f3a1c",
      "ts": "2026-06-30T14:02:11Z",
      "changeset_hash": "sha256:9c1f...e42b",
      "status": "applied"
    }
  }
}

3. m2-ledger service environment variables

m2-ledger is deployed as a Coolify app on the coolify network (constitution VI — no secrets in the image; all of the below are injected at runtime as env vars, never committed).

Var Purpose Default Notes
LEDGER_DB_PATH Path to the SQLite tx-log database file. — (required) Single source of truth; balances are always derived by folding this log (data-model.md §Wallet), never a separately-writable balance table.
LEDGER_SERVICE_KEYS Comma-separated list of valid service-class API keys. — (required) Accepted via X-API-Key header for service endpoints (§4).
LEDGER_ADMIN_KEYS Comma-separated list of valid admin-class API keys. — (required) Accepted via X-API-Key header for admin endpoints (§4). Keep this set small; these mint credit and can trigger snapshots.
LEDGER_PLATFORM_PCT Default platform cut applied on /tx/install when the request body omits platform_pct. 0.10 UNCONFIRMED — data-model.md/ledger-api.md flag this as a default pending confirmation, not a locked value.
LEDGER_STARTER_GRANT Default credit amount minted by /grant/starter when the request body omits amount. 100 UNCONFIRMED — same flag as above; ledger-api.md invariant 5 lists both defaults as config-not-code.
REGISTRY_REPO_URL Forgejo repo URL (m2/market-registry) that /snapshot commits audit/YYYY-MM-DD.json into. — (required) Used by both the admin-triggered snapshot and the daily cron snapshot.
FORGEJO_TOKEN Forgejo API token used to author the snapshot commit above. — (required) Scope to the single registry repo; do not reuse the CLI's forgejo_token from config.toml.

4. Key classes: service vs admin

Two API key classes, both passed via the X-API-Key header (contracts/ledger-api.md). Callers: the CLI, the Store, and the indexer use service keys; only ledger operators (humans/admin tooling) hold admin keys.

Endpoint Key class
GET /health none
GET /balance/{operator_id} service
POST /tx/install service
POST /tx/refund service
GET /tx?operator_id=&reason=&since= service
GET /license/{operator_id}/{listing_id} service
POST /grant/starter admin
POST /snapshot admin (also runs unauthenticated via daily cron, in-process)

Rule of thumb: anything that mints credit (starter grants) or exports the full ledger (snapshot) is admin-only. Everything a normal install/refund/balance-check flow needs is service-scoped — this is the key class that belongs in ~/.m2-market/config.toml's ledger_api_key.

5. Security rules

  1. No secrets in repos or container images. All keys/tokens in this document (ledger_api_key, memory_api_key, forgejo_token, LEDGER_SERVICE_KEYS, LEDGER_ADMIN_KEYS, FORGEJO_TOKEN) are injected at runtime — via config.toml on the machine for the CLI, or via Coolify env vars for m2-ledger. Never commit real values; example values above are placeholders only (constitution VI: canary-first, reversible deployment — "No secrets in repos or images; keys injected at runtime").
  2. ~/.m2-market/config.toml must be mode 0600. It is the only place all four live credentials (ledger, memory, Forgejo) sit together on a machine.
    chmod 600 ~/.m2-market/config.toml
    
  3. Admin keys (LEDGER_ADMIN_KEYS) are minting/export authority — scope distribution tightly (see §4); CLI configs should never carry an admin key.