Restricting access¶
RBAC decides what Axiom can see, and nothing else needs configuring. Discovery asks the API server which kinds the gateway's ServiceAccount may list, and offers exactly those. To change what appears in SQL, change the ClusterRoles.
That is the bound worth having, because the API server enforces it: a kind you have not granted cannot be read, whatever a query asks for.
One identity for every query
Until per-caller identity lands, anyone who can query a foreign table reads as the gateway. Grant the gateway only what every user of that database may see, and use Postgres grants to narrow it further per role. Giving an AI agent access shows a scoped role.
What the shipped role grants¶
gateway-rbac.yaml reads broadly and writes narrowly.
- Reads: everything in Kubernetes'
viewrole (workloads, ConfigMaps, Services, NetworkPolicies, Ingresses, Events), plus nodes, storage, CRDs, RBAC objects,events.k8s.ioand the metrics APIs. - Never Secrets. No rule in the shipped role reaches them.
- Writes: granted per resource in the
axiom-gatewayClusterRole: ConfigMaps and the example CRD.
Narrowing it¶
Reads come from axiom-gateway-read, an aggregated ClusterRole that collects
two sets of roles:
- every role labelled
rbac.authorization.k8s.io/aggregate-to-view: "true", which is Kubernetes' ownviewrole and any operator's; - every role labelled
axiom.dhilipkumars.github.io/aggregate-to-gateway: "true", which is the shippedaxiom-gateway-read-extra(nodes, storage, CRDs, RBAC objects, metrics) and any you add.
To grant less, apply your own copy of gateway-rbac.yaml: drop the
aggregate-to-view selector from axiom-gateway-read, and trim
axiom-gateway-read-extra to the kinds you want. A kind granted only get,
list and watch is readable and cacheable but not writable, and its table
says so.
Adding a custom resource¶
A custom resource is readable if its operator ships an aggregate-to-view
role. If it does not, label a read-only ClusterRole and the gateway's read role
picks it up:
kubectl apply -f - <<'YAML'
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: axiom-read-cnpg
labels:
axiom.dhilipkumars.github.io/aggregate-to-gateway: "true"
rules:
- apiGroups: ["postgresql.cnpg.io"]
resources: ["*"]
verbs: ["get", "list", "watch"]
YAML
Name the API group rather than using "*": a rule that reaches the core
group with a wildcard grants Secrets.
Making a kind writable¶
Add its verbs to the axiom-gateway ClusterRole, for example:
kubectl patch clusterrole axiom-gateway --type=json -p='[{"op":"add","path":"/rules/-","value":
{"apiGroups":["apps"],"resources":["deployments"],"verbs":["get","list","watch","update"]}}]'
After a change¶
- A new grant is seen on the next import, with no restart.
- Revoking or narrowing one needs a gateway restart, because the gateway caches what it is allowed.
- Either way, import again. Foreign tables are catalog objects and do not follow an RBAC change on their own. Initialize shows how to check what the gateway offers now.