-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathconfig.toml
More file actions
138 lines (125 loc) · 6.24 KB
/
Copy pathconfig.toml
File metadata and controls
138 lines (125 loc) · 6.24 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
# Garrison control plane — SchemaForge service configuration (development).
#
# SchemaForge is an application on acton-service, so everything outside the
# `[schema_forge.*]` extension is acton-service's canonical config surface.
# Discovery order, highest first: `--config <PATH>`, then `./config.toml`
# (this file), `~/.config/acton-service/schemaforge/config.toml`,
# `/etc/acton-service/schemaforge/config.toml`, with `ACTON_*` env vars
# layering over whichever file was loaded.
#
# This file configures the control plane only. The agent daemon reads
# `garrison.toml` and `acton-ai.toml`; the two do not share a config.
# PostgreSQL backend. The `schemaforge` CLI ships one backend per build and the
# binary in use here is the PostgreSQL flavor; a SurrealDB URL would be refused
# at startup with "backend not enabled in this build". Override the URL per
# environment with `ACTON_DATABASE_URL` rather than editing this file.
[database]
url = "postgres://garrison:garrison@127.0.0.1:5432/garrison_plane"
max_connections = 50
min_connections = 5
# SurrealDB backend, for a SurrealDB-flavored build. Mutually exclusive with
# [database] above — declaring both is a startup error, on purpose.
# [surrealdb]
# url = "ws://localhost:8000"
# namespace = "garrison"
# database = "dev"
# Credentials belong in the environment, not here:
# ACTON_SURREALDB_USERNAME / ACTON_SURREALDB_PASSWORD
# PASETO v4 local tokens. Mint the key with `task plane:key` — `keys/` is
# gitignored and the file must be mode 0600.
[token]
format = "paseto"
version = "v4"
purpose = "local"
key_path = "./keys/paseto.key"
issuer = "garrison-control-plane"
# ---------------------------------------------------------------------------
# Principal claims — Entra ID identity projected onto Cedar.
#
# These map PASETO `custom` claims onto optional attributes of
# `Forge::Principal` so hand-written policies in policies/custom/ can compare
# e.g. `principal.entra_object_id` against a resource field. The `source =
# { user_field = "..." }` form reads the column off the console User row at
# every login and refresh; the columns come from `schemas/user.schema`, the
# deployment's override of the system User schema. Startup validates that
# both sources exist, so `task plane:apply` must run before the plane boots
# with this section enabled. That is the intended failure.
#
# `required = false` on both, and this is not a softening. `required` is
# enforced against every bearer the plane accepts, not only console logins:
# the `enrollee` artifact a daemon redeems and the service bearers minted with
# `schemaforge token generate` carry no `entra_object_id`, and `required =
# true` would 401 every enrollment and every hook call. The claim is still
# projected for every console login that has one, and the policies that care
# (policies/custom/directory-identity.cedar) test `principal has
# entra_object_id` and refuse when it is absent. Fail-closed is on the policy,
# not on the token.
[schema_forge.authz.principal_claims.entra_object_id]
type = "string"
required = false
source = { user_field = "entra_object_id" }
[schema_forge.authz.principal_claims.org_slug]
type = "string"
required = false
source = { user_field = "org_slug" }
# Mappings are read at startup only. Changing them needs a daemon restart.
# ---------------------------------------------------------------------------
# ---------------------------------------------------------------------------
# Lifecycle hooks.
#
# Three bindings, all `before_validate`, all served by `hooks-service/` in this
# repo (`task hooks:serve`), all `required = true`:
#
# Redemption the enrollment decision. Creating a Redemption is the only
# way a machine joins the fleet; the hook adjudicates the token
# and provisions the install and its credential.
# AuditEvent the verifying ingest. The hook re-links the shipped entry
# against the trail's AuditChain and refuses forks and edits.
# PolicyBundle the publish gate. The hook self-tests the rules and stamps
# the checksum when a bundle moves to `published`.
#
# The hook names are `{Schema}Hooks.BeforeValidate`, which is what
# `schemaforge hooks generate` writes into `hooks_descriptor.bin`; the plane
# validates every binding against that descriptor at startup.
[schema_forge.hooks]
enabled = true
default_timeout_ms = 15000
max_concurrent_async = 100
# Development only. The hook runs on loopback here, so the field snapshot and
# the bearer SchemaForge presents never leave the machine. In any deployment
# where the hook is a separate host this must go back to false and the endpoint
# must be `https://`, or the enrollment payload and a replayable credential are
# readable by anything on the path.
allow_plaintext = true
[[schema_forge.hooks.bindings]]
schema = "Redemption"
event = "BeforeValidate"
endpoint = "http://127.0.0.1:9391"
timeout_ms = 15000
# `required = true` is the whole point. With `false`, a hook that is down would
# be logged and the create would proceed — persisting a Redemption that admitted
# nobody, refused nobody, and left a daemon believing it had enrolled. Failing
# the request is the only honest outcome.
required = true
descriptor_path = "./hooks-service/hooks_descriptor.bin"
# With `false`, an unreachable hook would persist an entry nobody verified and
# advance nothing; the daemon would take the 201 as an ack and drop it from its
# backlog. A 503 is what makes the daemon keep the entry and retry.
[[schema_forge.hooks.bindings]]
schema = "AuditEvent"
event = "BeforeValidate"
endpoint = "http://127.0.0.1:9391"
timeout_ms = 15000
required = true
descriptor_path = "./hooks-service/hooks_descriptor.bin"
# With `false`, a bundle could move to `published` with an empty checksum and
# untested rules, and every install would refuse it on pull for a reason the
# console never saw. Refusing the publish is the honest outcome.
[[schema_forge.hooks.bindings]]
schema = "PolicyBundle"
event = "BeforeValidate"
endpoint = "http://127.0.0.1:9391"
timeout_ms = 15000
required = true
descriptor_path = "./hooks-service/hooks_descriptor.bin"
# ---------------------------------------------------------------------------