Authority configuration¶
The flat configuration hub remains the compatibility route. This page is the canonical source-checked field reference for its family, including nested tables and list rows.
Paths in the tables are relative to [authority]. Each row gives the serde
type and source default or unset meaning; keep keys and certificates in
protected files. Check parsing and authority cross-field rules with
gdsgate doctor --config <PATH> --json, then follow the multi-node control
plane guide.
[authority]¶
Used by: Authority.
What Authority's registration listener
([endpoints].authority_enroll) presents, and whether Authority opens
an emergency socket on its own host. Authority's control plane needs nothing
here: it runs mutual TLS off the transport CA the cluster is built on, and both
ends of it are nodes of this cluster. Registration is the one Authority surface
whose peer is not one yet.
| Key | Type | Default | Purpose |
|---|---|---|---|
enroll_cert_file |
string | unset | PEM certificate chain the registration listener presents. Unset, the listener speaks cleartext h2c. |
enroll_key_file |
string | unset | PEM private key for enroll_cert_file. Naming one half of the pair and not the other is refused at start-up. Accepts the secret-reference notation; a helper or variable named here is re-run on each certificate rotation, not only at start-up. |
emergency_socket |
string | unset | Path of the emergency administrative socket. Unset, there is no socket. |
ca_kms_key |
string (optional) | unset | Which [[kms_keys]] entry wraps the CA signing seeds. |
[authority]
enroll_cert_file = "/etc/gdsgate/enroll-fullchain.pem"
enroll_key_file = "/etc/gdsgate/enroll-key.pem"
Cleartext is what this listener has always spoken and what an internal network
is entitled to keep: the one-time provision token is the proof either way, and
on a segment nobody else is on there is nothing to hide it from. Name a
certificate where that segment is the internet. Everything crossing this
listener is a credential in flight, a node's provision token and a workload's
platform token on IssueWorkloadIdentity / RenewWorkloadIdentity, which sit on
the same port, so an exposed deployment without one hands each of them to whoever
is in the path.
gdsgate obtains no certificate, as it obtains none for
[proxy].public_cert_file: an ACME client or a corporate issuer writes
the two files and replaces them on renewal, and the listener re-reads them while
it runs. See
Renewing a listener certificate.
The same pair can serve both listeners where one name fronts them.
Registration listener has no transitional mode
The listener is either cleartext h2c or TLS. It cannot be both, and nothing
negotiates between them. The moment enroll_cert_file takes effect, every
node's [enroll].endpoint has to change from http:// to https:// in the
same rollout: a node still configured with http:// gets a connection that
goes nowhere, and a node configured with https:// before the certificate
exists gets the same.
This affects a hand-configured node hardest, because nothing on it tracks the change. What it costs depends on when it is noticed: a node that already holds an identity keeps working off it and renews over the control plane, which is a different listener and unaffected, so the failure surfaces only on a first registration, or on a node that has lost its state directory. Plan it as one change over the fleet, not as a per-node migration.
Turning it back off has the same shape in reverse.
The emergency administrative socket¶
Unset is the default and means the socket does not exist. A cluster that never has to be repaired from its own host grows no surface by upgrading.
It is there for one situation: the policy refuses everybody, so neither a person through the gateway nor the administrative certificate decides anything, and the cluster cannot be repaired from where it is normally administered. The socket answers on the Authority host, and reaching it means having a shell there, which is deliberately harder than the everyday path.
The filesystem is the whole admission. Authority creates the socket 0600 and
refuses to start if it comes up reachable by another account. The directory
holding it is created 0700 when absent and read, not rewritten, when present, so pointing the key at a directory of your own does not change that
directory; a directory other accounts can write to is refused instead, because
anybody who can write there could unlink the socket and answer in its place,
which no permission on the socket itself would prevent. Point the key at a
directory the service account owns; the shipped systemd unit has a commented
RuntimeDirectory=gdsgate / RuntimeDirectoryMode=0700 pair to uncomment beside
this key, which gives exactly the path above and takes the directory away again
when the service stops. Connections are accepted from the socket's owner and from
root, and from nobody else.
It does not skip the policy. A call arriving here carries no identity, no token
and no address, and offering any of them is refused, not ignored. It is
decided by Cedar over User::"gdsgate-break-glass", the principal
every accepted policy must keep able to edit the policy.
That is what makes a lockout curable through it, and it is also why nothing else
comes with it: outside editPolicy the socket reaches only what a rule names,
which in the shipped baseline is nothing.
It carries PullPolicy, PushPolicy, the catalog calls and the registry
listings, and refuses every other method by name. Audit rows from it name
gdsgate-break-glass as the actor and carry admin_channel=emergency-socket in
their detail, so an emergency is legible as one when the chain is read.
gdsgate doctor reports it, present, owner-only, and the directory around it, so
a mode widened after the fact is found before it matters. The walkthrough is in
Lock-out and recovery.
gdsgate doctor reports which of the two registration modes is in force
(config.authority.enroll_listener), on the node side which of them that node is
configured for (config.enroll.trust), and, where the
join relay is bound, what registration crossing it travels as
(config.proxy.join_relay). It reports the join on the client-facing listener in
both states, with the call budget and both lane ceilings in
force (config.proxy.public_join).
Wrapping the CA signing seeds¶
Unset is the default, and every CA generation goes on being stored the way it
always has been: 32 bytes in the database's ca_private_key.seed column,
readable by whoever can read the table. Naming a key here wraps every seed
written from then on: the column holds ciphertext instead, opened once when a
generation is loaded, at start-up and when a rotation publishes a new one, and
never on the path that signs a certificate.
The value is a name, not a secret reference.
ca_private_key has no column to carry one, so the key is named once, here,
out of [[kms_keys]], and every row records the
fingerprint of the key it was wrapped under; starting under a differently
named key is a refusal naming both, not an unwrap that produces nothing
readable. Rows already in the clear go on being read.
gdsgate authority keys wrap-ca-seeds converts them, and a table that is only
partway converted is a table a cluster keeps running on.