Skip to content

Commit

Permalink
feat: Add openfga v1
Browse files Browse the repository at this point in the history
  • Loading branch information
nsklikas committed Nov 22, 2023
1 parent f9c7e60 commit 8f0bcad
Show file tree
Hide file tree
Showing 5 changed files with 250 additions and 0 deletions.
64 changes: 64 additions & 0 deletions docs/json_schemas/openfga/v1/provider.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
{
"title": "ProviderSchema",
"description": "Provider schema for OpenFGA.",
"type": "object",
"properties": {
"unit": {
"$ref": "#/definitions/BaseModel"
},
"app": {
"$ref": "#/definitions/OpenFGAProviderData"
}
},
"required": [
"app"
],
"definitions": {
"BaseModel": {
"title": "BaseModel",
"type": "object",
"properties": {}
},
"OpenFGAProviderData": {
"title": "OpenFGAProviderData",
"type": "object",
"properties": {
"grpc_api_url": {
"title": "GRPC URL",
"description": "The url of the grpc API.",
"type": "string"
},
"http_api_url": {
"title": "HTTP URL",
"description": "The url of the http API.",
"type": "string"
},
"token_secret_id": {
"title": "Secret ID of the OpenFGA token",
"description": "Secret ID of the preshared token to be used to connect to the OpenFGA service.",
"type": "string"
},
"token": {
"title": "Secret ID of the OpenFGA token",
"description": "The preshared token to be used to connect to the OpenFGA service, to be used when juju secrets are not available.",
"type": "string"
},
"store_id": {
"title": "OpenFGA store ID",
"description": "ID of the authentication stored that was created.",
"examples": [
"01GK13VYZK62Q1T0X55Q2BHYD6"
],
"type": "string"
}
},
"required": [
"grpc_api_url",
"http_api_url",
"token_secret_id",
"token",
"store_id"
]
}
}
}
40 changes: 40 additions & 0 deletions docs/json_schemas/openfga/v1/requirer.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
{
"title": "RequirerSchema",
"description": "Requirer schema for OpenFGA.",
"type": "object",
"properties": {
"unit": {
"$ref": "#/definitions/BaseModel"
},
"app": {
"$ref": "#/definitions/OpenFGARequirerData"
}
},
"required": [
"app"
],
"definitions": {
"BaseModel": {
"title": "BaseModel",
"type": "object",
"properties": {}
},
"OpenFGARequirerData": {
"title": "OpenFGARequirerData",
"type": "object",
"properties": {
"store_name": {
"title": "Authorization store name",
"description": "The name of the authorization store.",
"examples": [
"auth_store"
],
"type": "string"
}
},
"required": [
"store_name"
]
}
}
}
67 changes: 67 additions & 0 deletions interfaces/openfga/v1/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
# `openfga`

## Usage

This relation interface describes the expected behaviour of any charm claiming to be able to interact with a OpenFGA.

In most cases, this will be accomplished using the [openfga library](https://github.com/canonical/openfga-operator/blob/main/charms/openfga-k8s/lib/charms/openfga_k8s/v0/openfga.py), although charm developers are free to provide alternative libraries as long as they fulfil the behavioural and schematic requirements described in this document.

## Direction

```mermaid
flowchart TD
Requirer -- store_name --> Provider
Provider -- store_id, token_secret_id, token, grpc_api_url, http_api_url --> Requirer
```

As with all Juju relations, the `openfga` interface consists of two parties: a Provider (openfga charm), and a Requirer (application charm). The Requirer will be expected to expose an authentication store name, and the Provider will create and forward new unique credentials (along with other optional fields), which can be used to access the OpenFGA store.

## Behavior

Both the Requirer and the Provider need to adhere to the following criteria to be considered compatible with the interface.

### Provider
- Is expected to create an authentication store in OpenFGA when the requirer provides the `store_name` field.
- Is expected to expose to the Requirer `store_id`, `token_secret_id`, `token`, `grpc_api_url` and `http_api_url` fields in the *application* databag.

### Requirer
- Is expected to provide the `store_name` it requires in its application databag
- Is expected to use the `store_id`, `token_secret_id`, `token`, `grpc_api_url` and `http_api_url` fields, when exposed by the `Provider`, to set up an OpenFGA connection.

## Relation Data

### Provider

[\[JSON Schema\]](./schemas/provider.json)

Provider exposes `store_id`, `token_secret_id`, `token`, `grpc_api_url` and `http_api_url` fields in the **application** databag.


#### Example
```yaml
relation-info:
- endpoint: openfga
related-endpoint: openfga
application-data:
token_secret_id: "10559c09-6416-40b0-9402-54b6e28edd3a"
token: null
store_id: "01GK13VYZK62Q1T0X55Q2BHYD6"
grpc_api_url: "http://10.10.0.17:8081"
http_api_url: "http://10.10.0.17:8080"
```
### Requirer
[\[JSON Schema\]](./schemas/requirer.json)
The Requirer exposes the store name for which authorization is requested in the **application** databag.
#### Example
```yaml
relation-info:
- endpoint: openfga
related-endpoint: openfga
application-data:
store_name: "test-store"
```
3 changes: 3 additions & 0 deletions interfaces/openfga/v1/charms.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
providers: []

requirers: []
76 changes: 76 additions & 0 deletions interfaces/openfga/v1/schema.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
# Copyright 2023 Canonical
# See LICENSE file for licensing details.
"""This file defines the schemas for the provider and requirer sides of the openfga interface.
It exposes two interfaces.schema_base.DataBagSchema subclasses called:
- ProviderSchema
- RequirerSchema
Examples:
ProviderSchema:
unit: <empty>
app: {"openfga":
{"grpc_api_url": "http://10.10.0.17:8081",
"http_api_url": "http://10.10.0.17:8080",
"token": "test-token",
"token_secret_id": null,
"store_id": "01GK13VYZK62Q1T0X55Q2BHYD6",
}
}
RequirerSchema:
unit: <empty>
app: {"store_name": "test-store-name"}
"""
from interface_tester.schema_base import DataBagSchema
from pydantic import BaseModel, Field


class OpenFGAProviderData(BaseModel):
grpc_api_url: str = Field(
description=("The url of the grpc API."),
title="GRPC URL",
)
http_api_url: str = Field(
description=("The url of the http API."),
title="HTTP URL",
)
token_secret_id: str = Field(
description=(
"Secret ID of the preshared token to be used to connect to"
" the OpenFGA service."
),
title="Secret ID of the OpenFGA token",
)
token: str = Field(
description=(
"The preshared token to be used to connect to the OpenFGA "
"service, to be used when juju secrets are not available."
),
title="Secret ID of the OpenFGA token",
)
store_id: str = Field(
description="ID of the authentication stored that was created.",
title="OpenFGA store ID",
examples=["01GK13VYZK62Q1T0X55Q2BHYD6"],
)


class ProviderSchema(DataBagSchema):
"""Provider schema for OpenFGA."""

app: OpenFGAProviderData


class OpenFGARequirerData(BaseModel):
store_name: str = Field(
description="The name of the authorization store.",
title="Authorization store name",
examples=["auth_store"],
)


class RequirerSchema(DataBagSchema):
"""Requirer schema for OpenFGA."""

app: OpenFGARequirerData

0 comments on commit 8f0bcad

Please sign in to comment.