Files
datastore/docker/server/datastore-iam.xml

109 lines
5.3 KiB
XML

<clickhouse>
<!--
Hanzo IAM user directory. Every caller authenticates with a Hanzo IAM access token
(native protocol: the client's JWT login; HTTP: Authorization: Bearer). There are no
stored users and no database passwords for them: the directory verifies the token
against the issuer's published keys, names an ephemeral user after its `sub`, and
decides the roles the session holds from the token's claims. The session's
organization, read in SQL as currentOrg(), is the bearer's home org: the first entry
of the signed `orgs` membership set. The `owner` claim decides nothing; it names the
org of the application a token was minted through.
Nothing here is secret: the keys are fetched from the issuer's public JWKS.
A program is matched by the IAM application ROW its token was minted for, `<owner>/<name>`,
which IAM signs as the token's `sub`, and by its client id `azp`, which is the row's name
(hanzoai/universe charts/app/values/hanzo/iam-provision.yaml converges each platform app as
the row admin/<org>-<app> with client id <org>-<app>). Rows of the reserved admin org are
the platform's alone. A client id by itself is first-come across every org, so it names
nothing: a tenant that registers its own `hanzo-event` gets `sub` evilcorp/hanzo-event and
matches no rule here. admin/hanzo-event is the event app (the sink), admin/hanzo-o11y the
telemetry plane and the owner of its schema, admin/hanzo-cloud the rest of the cloud host.
Nobody here reads the event plane across orgs. Each process reads as the org whose token it
holds, or not at all; a cross-org reader is a decision the platform owner has not made.
superadmin, schema and platform are declared in users.d (datastore-iam-roles.xml) so they
exist before any SQL runs; tenant, reader, writer and sink and the event plane's row policies
are created by the o11y schema migration 0005, run by the o11y application under `schema`. A
role named here that does not exist yet is not granted, and the server logs a warning.
Documentation: docs/en/operations/external-authenticators/iam.md.
Ships only in images whose binary knows the `iam` directory type: an older
binary refuses to start on an unknown user directory.
-->
<!-- A table engine needs a grant. An engine that reads another database or another server
(Distributed, Merge, Buffer, URL, a database engine) is otherwise every creator's, and the
IAM roles hold only the engines their migrations use. A users.xml user without <grants>,
and anyone holding ALL, keeps every engine; a SQL user that creates tables needs
GRANT TABLE ENGINE ON <engine>. -->
<access_control_improvements>
<table_engines_require_grant>true</table_engines_require_grant>
</access_control_improvements>
<user_directories>
<iam>
<issuer>https://hanzo.id</issuer>
<audience>datastore</audience>
<!-- SuperAdmin holds only for a token signed with the admin org's own key. -->
<superadmin_kid>cert-admin</superadmin_kid>
<!-- Every identity. Carries the org confinement: USING org = currentOrg(). -->
<roles>
<tenant/>
</roles>
<!-- The roles a GRANT made under an IAM identity may name: the three the event plane's
migration gives rights to (schema's grant option exists for them), reader also being
the role platform gives its own tables to. No user and no other role: a grant option
cannot reach a password user or a role outside this set. SuperAdmin's grants may name
anyone. -->
<grantees>
<reader/>
<writer/>
<sink/>
</grantees>
<rules>
<!-- Programs: client_credentials and workload tokens, matched by the application row
they were minted for (sub) and held by its own client (azp). -->
<!-- The event app: INSERT on event.fact and nothing else. -->
<rule>
<application>admin/hanzo-event</application>
<role>sink</role>
</rule>
<!-- The telemetry plane writes its tables and runs its own migrations. -->
<rule>
<application>admin/hanzo-o11y</application>
<role>writer</role>
</rule>
<rule>
<application>admin/hanzo-o11y</application>
<role>schema</role>
</rule>
<!-- The cloud host owns the hanzo database. -->
<rule>
<application>admin/hanzo-cloud</application>
<role>platform</role>
</rule>
<!-- People: not a program, and a member of at least one org. -->
<rule>
<person/>
<role>reader</role>
</rule>
<!-- SuperAdmin: a person whose home org is admin, signed with superadmin_kid. -->
<rule>
<superadmin/>
<role>superadmin</role>
</rule>
</rules>
</iam>
</user_directories>
</clickhouse>