authzed / spicedb-operator

Kubernetes controller for managing instances of SpiceDB
Apache License 2.0
62 stars 26 forks source link

Proposal: Operator-boostrapped schema #259

Open ecordell opened 10 months ago

ecordell commented 10 months ago

Ref: #115

The goal is to allow a user to supply a bootstrap file with schema and relationships to SpiceDB on start, via the kube apis.

Today

This is possible today via use of patches:

apiVersion: authzed.com/v1alpha1
kind: SpiceDBCluster
metadata:
  name: dev
spec:
  config:
    datastoreEngine: memory
    datastoreBootstrapFiles: /etc/bootstrap/init.yaml
  secretName: dev-spicedb-config
  patches:
  - kind: Deployment
    patch:
      spec:
        template:
          spec:
            volumes:
            - name:  bootstrap
              configMap:
                name: spicedb-bootstrap
            containers:
            - name: spicedb
              volumeMounts:
              - name: bootstrap
                mountPath: /etc/bootstrap
---
apiVersion: v1
kind: ConfigMap
metadata:
  name: spicedb-bootstrap
data:
  init.yaml: |
    schema: |-
      definition user {}

      definition document {
          relation writer: user
          relation reader: user

          permission edit = writer
          permission view = reader + edit
      }
    relationships: |-
      document:firstdoc#writer@user:tom
      document:firstdoc#reader@user:fred
      document:seconddoc#reader@user:tom

But this will bootstrap every time a spicedb starts or is re-scheduled, which is not ideal.

Proposal: Managed schema

A new field, bootstrapConfigMapName will be added:

apiVersion: authzed.com/v1alpha1
kind: SpiceDBCluster
metadata:
  name: dev
spec:
  config:
    datastoreEngine: memory
  secretName: dev-spicedb-config
  bootstrapConfigMapName: spicedb-bootstrap
---
apiVersion: v1
kind: ConfigMap
metadata:
  name: spicedb-bootstrap
data:
  init.yaml: |
    schema: |-
      definition user {}

      definition document {
          relation writer: user
          relation reader: user

          permission edit = writer
          permission view = reader + edit
      }
    relationships: |-
      document:firstdoc#writer@user:tom
      document:firstdoc#reader@user:fred
      document:seconddoc#reader@user:tom

Similarly to how migrations are handled, when bootstrapConfigMap is set, the operator will:

Any changes to the configmap will re-run the job (via comparison to the hash in the status).

We will assume that anyone using this feature wants the bootstrap to be continually run on changes; we can document a Job spec that will run once for anyone that doesn't want continual reconciliation.

Alternatives Considered

New APIs

A Schema or Bootstrap API might be nice, but the boostrap yaml file format is already well-defined and is consumable by SpiceDB and zed, so a ConfigMap is somewhat more straightforward (i.e. users can can take a file from playground and directly create it as a configmap with kubectl). There are also some in-flight discussions for changes to the local schema filesystem representation that we don't want to box ourselves out of.

SpiceDB --datastore-bootstrap-files instead of zed

The same general effect could be achieved by selectively turning the --datastore-bootstrap-files flag on and off on a SpiceDB pod, but it means that the pods will need to be rolled again after a successful bootstrap (to disable the boostrap). The Job approach avoids this.