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/*_tokenpairs are required forinstall/publish/searchto function;wallet/showneed at leastledger_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
- 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 — viaconfig.tomlon the machine for the CLI, or via Coolify env vars form2-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"). ~/.m2-market/config.tomlmust be mode0600. It is the only place all four live credentials (ledger, memory, Forgejo) sit together on a machine.chmod 600 ~/.m2-market/config.toml- Admin keys (
LEDGER_ADMIN_KEYS) are minting/export authority — scope distribution tightly (see §4); CLI configs should never carry an admin key.