|
| 1 | +# OpenFGA Controller Documentation |
| 2 | + |
| 3 | +This documentation helps you deploy an authorization model and ensures your deployments stay in sync with the latest authorization model from OpenFGA. The OpenFGA controller automates the synchronization between your deployments and the authorization models. |
| 4 | + |
| 5 | +## Steps |
| 6 | + |
| 7 | +### 1. Create an Authorization Model |
| 8 | + |
| 9 | +Make an authorization request: |
| 10 | + |
| 11 | +```yaml |
| 12 | +apiVersion: extensions.openfga-controller/v1 |
| 13 | +kind: AuthorizationModelRequest |
| 14 | +metadata: |
| 15 | + name: documents |
| 16 | +spec: |
| 17 | + version: 1.1.1 |
| 18 | + authorizationModel: | |
| 19 | + model |
| 20 | + schema 1.1 |
| 21 | + |
| 22 | + type user |
| 23 | + |
| 24 | + type document |
| 25 | + relations |
| 26 | + define foo: [user] |
| 27 | + define reader: [user] |
| 28 | + define writer: [user] |
| 29 | + define owner: [user] |
| 30 | +``` |
| 31 | +
|
| 32 | +This request will: |
| 33 | +- Create a store with the same name in OpenFGA. |
| 34 | +- Create a Kubernetes resource `Store`. |
| 35 | + |
| 36 | +```yaml |
| 37 | +apiVersion: extensions.openfga-controller/v1 |
| 38 | +kind: Store |
| 39 | +metadata: |
| 40 | + labels: |
| 41 | + authorization-model: documents |
| 42 | + name: documents |
| 43 | + namespace: default |
| 44 | + ownerReferences: |
| 45 | + - apiVersion: extensions.openfga-controller/v1 |
| 46 | + blockOwnerDeletion: true |
| 47 | + controller: true |
| 48 | + kind: AuthorizationModelRequest |
| 49 | + name: documents |
| 50 | + uid: <SOME_ID> |
| 51 | +spec: |
| 52 | + id: 01J1CE2YAH98MKN2SZ8BJ0XYPZ |
| 53 | +
|
| 54 | +``` |
| 55 | + |
| 56 | +- Create the authorization model in OpenFGA. |
| 57 | +- Save the authorization model ID in a Kubernetes resource `AuthorizationModel`. |
| 58 | + |
| 59 | +```yaml |
| 60 | +apiVersion: extensions.openfga-controller/v1 |
| 61 | +kind: AuthorizationModel |
| 62 | +metadata: |
| 63 | + labels: |
| 64 | + authorization-model: documents |
| 65 | + name: documents |
| 66 | + namespace: default |
| 67 | + ownerReferences: |
| 68 | + - apiVersion: extensions.openfga-controller/v1 |
| 69 | + blockOwnerDeletion: true |
| 70 | + controller: true |
| 71 | + kind: AuthorizationModelRequest |
| 72 | + name: documents |
| 73 | + uid: <SOME_ID> |
| 74 | +spec: |
| 75 | + authorizationModel: "model\n schema 1.1\n \ntype user\n \ntype document\n relations\n |
| 76 | + \ define foo: [user]\n define reader: [user]\n define writer: [user]\n |
| 77 | + \ define owner: [user]\n" |
| 78 | + instance: |
| 79 | + createdAt: "2024-05-26T13:11:59Z" |
| 80 | + id: 01HYTGF0VHRM5ASHSBJJRQG87N |
| 81 | + version: 1.1.1 |
| 82 | + latestModels: [] |
| 83 | +``` |
| 84 | + |
| 85 | +### 2. Deployment with Label |
| 86 | + |
| 87 | +Given a deployment with the label `openfga-store` set to the name of the authorization request: |
| 88 | + |
| 89 | +```yaml |
| 90 | +apiVersion: apps/v1 |
| 91 | +kind: Deployment |
| 92 | +metadata: |
| 93 | + labels: |
| 94 | + openfga-store: documents |
| 95 | + app: annotated-curl |
| 96 | + name: annotated-curl |
| 97 | +spec: |
| 98 | + replicas: 1 |
| 99 | + selector: |
| 100 | + matchLabels: |
| 101 | + app: annotated-curl |
| 102 | + template: |
| 103 | + metadata: |
| 104 | + labels: |
| 105 | + app: annotated-curl |
| 106 | + spec: |
| 107 | + containers: |
| 108 | + - name: main |
| 109 | + image: curlimages/curl:8.7.1 |
| 110 | + command: ["sleep", "9999999"] |
| 111 | +``` |
| 112 | + |
| 113 | +The environment variable `OPENFGA_AUTH_MODEL_ID` will be set to the latest created authorization model ID from OpenFGA. |
| 114 | + |
| 115 | +```yaml |
| 116 | +apiVersion: apps/v1 |
| 117 | +kind: Deployment |
| 118 | +metadata: |
| 119 | + annotations: |
| 120 | + openfga-auth-id-updated-at: "2024-05-26T13:11:59Z" |
| 121 | + openfga-auth-model-version: 1.1.1 |
| 122 | + openfga-store-id-updated-at: "2024-06-27T08:48:03Z" |
| 123 | + labels: |
| 124 | + app: annotated-curl |
| 125 | + openfga-store: documents |
| 126 | + name: annotated-curl |
| 127 | + namespace: default |
| 128 | +spec: |
| 129 | + replicas: 1 |
| 130 | + selector: |
| 131 | + matchLabels: |
| 132 | + app: annotated-curl |
| 133 | + template: |
| 134 | + metadata: |
| 135 | + labels: |
| 136 | + app: annotated-curl |
| 137 | + spec: |
| 138 | + containers: |
| 139 | + - command: |
| 140 | + - sleep |
| 141 | + - "9999999" |
| 142 | + env: |
| 143 | + - name: OPENFGA_STORE_ID |
| 144 | + value: 01J1CE2YAH98MKN2SZ8BJ0XYPZ |
| 145 | + - name: OPENFGA_AUTH_MODEL_ID |
| 146 | + value: 01HYTGF0VHRM5ASHSBJJRQG87N |
| 147 | + image: curlimages/curl:8.7.1 |
| 148 | + imagePullPolicy: IfNotPresent |
| 149 | + name: main |
| 150 | +```` |
| 151 | +
|
| 152 | +### 3. Update the Authorization Model |
| 153 | +To update the authorization model, make a request like below. The important part is the change in the authorizationModel since this is what the controller compares. |
| 154 | +
|
| 155 | +```yaml |
| 156 | +apiVersion: extensions.openfga-controller/v1 |
| 157 | +kind: AuthorizationModelRequest |
| 158 | +metadata: |
| 159 | + name: documents |
| 160 | +spec: |
| 161 | + version: 1.1.2 |
| 162 | + authorizationModel: | |
| 163 | + model |
| 164 | + schema 1.1 |
| 165 | + |
| 166 | + type user |
| 167 | + |
| 168 | + type document |
| 169 | + relations |
| 170 | + define foo: [user] |
| 171 | + define bar: [user] |
| 172 | + define reader: [user] |
| 173 | + define writer: [user] |
| 174 | + define owner: [user] |
| 175 | +``` |
| 176 | +
|
| 177 | +The controller will call OpenFGA and create the new authorization model. The controller will update the AuthorizationModel with the new reference and move the old instance to `latestModels`. |
| 178 | + |
| 179 | +```yaml |
| 180 | +apiVersion: extensions.openfga-controller/v1 |
| 181 | +kind: AuthorizationModel |
| 182 | +metadata: |
| 183 | + labels: |
| 184 | + authorization-model: documents |
| 185 | + name: documents |
| 186 | + namespace: default |
| 187 | + ownerReferences: |
| 188 | + - apiVersion: extensions.openfga-controller/v1 |
| 189 | + blockOwnerDeletion: true |
| 190 | + controller: true |
| 191 | + kind: AuthorizationModelRequest |
| 192 | + name: documents |
| 193 | + uid: <SOME_ID> |
| 194 | +spec: |
| 195 | + authorizationModel: "model\n schema 1.1\n \ntype user\n \ntype document\n relations\n |
| 196 | + \ define foo: [user]\n define bar: [user]\n define reader: [user]\n define |
| 197 | + writer: [user]\n define owner: [user]\n" |
| 198 | + instance: |
| 199 | + createdAt: "2024-06-27T09:14:27Z" |
| 200 | + id: 01J1CFK2XZMFYW3QP1GKH2R4KN |
| 201 | + version: 1.1.2 |
| 202 | + latestModels: |
| 203 | + - createdAt: "2024-05-26T13:11:59Z" |
| 204 | + id: 01HYTGF0VHRM5ASHSBJJRQG87N |
| 205 | + version: 1.1.1 |
| 206 | +``` |
| 207 | + |
| 208 | +The controller will update annotated deployments so that the example deployment will have its `OPENFGA_AUTH_MODEL_ID` environment variable updated. |
| 209 | + |
| 210 | +```yaml |
| 211 | +apiVersion: apps/v1 |
| 212 | +kind: Deployment |
| 213 | +metadata: |
| 214 | + annotations: |
| 215 | + openfga-auth-id-updated-at: "2024-06-27T09:14:27Z" |
| 216 | + openfga-auth-model-version: 1.1.2 |
| 217 | + openfga-store-id-updated-at: "2024-06-27T08:48:03Z" |
| 218 | + labels: |
| 219 | + app: annotated-curl |
| 220 | + openfga-store: documents |
| 221 | + name: annotated-curl |
| 222 | + namespace: default |
| 223 | +spec: |
| 224 | + replicas: 1 |
| 225 | + selector: |
| 226 | + matchLabels: |
| 227 | + app: annotated-curl |
| 228 | + template: |
| 229 | + metadata: |
| 230 | + labels: |
| 231 | + app: annotated-curl |
| 232 | + spec: |
| 233 | + containers: |
| 234 | + - command: |
| 235 | + - sleep |
| 236 | + - "9999999" |
| 237 | + env: |
| 238 | + - name: OPENFGA_STORE_ID |
| 239 | + value: 01J1CE2YAH98MKN2SZ8BJ0XYPZ |
| 240 | + - name: OPENFGA_AUTH_MODEL_ID |
| 241 | + value: 01J1CFK2XZMFYW3QP1GKH2R4KN |
| 242 | + image: curlimages/curl:8.7.1 |
| 243 | + imagePullPolicy: IfNotPresent |
| 244 | + name: main |
| 245 | +``` |
| 246 | + |
| 247 | +### 4. Set a Specific Version on Deployment |
| 248 | + |
| 249 | +To lock the `OPENFGA_AUTH_MODEL_ID` to a specific user-provided version, add the label `openfga-auth-model-version` and set it to the desired version. |
| 250 | + |
| 251 | +```yaml |
| 252 | +apiVersion: apps/v1 |
| 253 | +kind: Deployment |
| 254 | +metadata: |
| 255 | + labels: |
| 256 | + openfga-store: documents |
| 257 | + openfga-auth-model-version: "1.1.1" |
| 258 | + app: annotated-curl |
| 259 | + name: annotated-curl |
| 260 | +spec: |
| 261 | + replicas: 1 |
| 262 | + selector: |
| 263 | + matchLabels: |
| 264 | + app: annotated-curl |
| 265 | + template: |
| 266 | + metadata: |
| 267 | + labels: |
| 268 | + app: annotated-curl |
| 269 | + spec: |
| 270 | + containers: |
| 271 | + - name: main |
| 272 | + image: curlimages/curl:8.7.1 |
| 273 | + command: ["sleep", "9999999"] |
| 274 | +``` |
| 275 | + |
| 276 | +By applying the above, the `OPENFGA_AUTH_MODEL_ID` will be set to the authorization model ID with version label `1.1.1`. |
| 277 | + |
| 278 | +```yaml |
| 279 | +apiVersion: apps/v1 |
| 280 | +kind: Deployment |
| 281 | +metadata: |
| 282 | + annotations: |
| 283 | + openfga-auth-id-updated-at: "2024-06-27T09:20:14Z" |
| 284 | + openfga-auth-model-version: 1.1.1 |
| 285 | + openfga-store-id-updated-at: "2024-06-27T08:48:03Z" |
| 286 | + labels: |
| 287 | + app: annotated-curl |
| 288 | + openfga-auth-model-version: 1.1.1 |
| 289 | + openfga-store: documents |
| 290 | + name: annotated-curl |
| 291 | + namespace: default |
| 292 | +spec: |
| 293 | + replicas: 1 |
| 294 | + selector: |
| 295 | + matchLabels: |
| 296 | + app: annotated-curl |
| 297 | + template: |
| 298 | + metadata: |
| 299 | + labels: |
| 300 | + app: annotated-curl |
| 301 | + spec: |
| 302 | + containers: |
| 303 | + - command: |
| 304 | + - sleep |
| 305 | + - "9999999" |
| 306 | + env: |
| 307 | + - name: OPENFGA_STORE_ID |
| 308 | + value: 01J1CE2YAH98MKN2SZ8BJ0XYPZ |
| 309 | + - name: OPENFGA_AUTH_MODEL_ID |
| 310 | + value: 01HYTGF0VHRM5ASHSBJJRQG87N |
| 311 | + image: curlimages/curl:8.7.1 |
| 312 | + imagePullPolicy: IfNotPresent |
| 313 | + name: main |
| 314 | +``` |
0 commit comments