Skip to content

Commit

Permalink
Merge branch 'dev'
Browse files Browse the repository at this point in the history
  • Loading branch information
SelligtomGit86 committed Feb 21, 2025
2 parents ccc22ff + 0f41f91 commit eae36ea
Show file tree
Hide file tree
Showing 12 changed files with 603 additions and 237 deletions.
2 changes: 2 additions & 0 deletions .github/workflows/test-extension.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,11 @@ on:
push:
branches:
- main
- dev
pull_request:
branches:
- main
- dev

jobs:
test:
Expand Down
79 changes: 79 additions & 0 deletions documentation/docs/plugins/keypairsexposition.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
---
sidebar_position: 4
---

import Terminal from '@site/src/components/Terminal';

# Exposing Biscuit Public Keys


Biscuit tokens rely on public key cryptography for secure, decentralized authorization. To enable verification, public keys need to be exposed to services that will validate Biscuit tokens.

This guide explains how to configure public key exposition in an Otoroshi environment using the Biscuit extension.

## Introduction

To expose your Biscuit public keys, you need to create a dedicated endpoint in your API gateway.

You can use the recommended URL for this exposition :

```
/.well-known/biscuit-web-keys
```

This endpoint will serve the list of public keys that can be used to verify Biscuit tokens issued by your system.

## Prerequisites

1. **Create one Biscuit KeyPair**
- Go to the **Biscuit keypairs** section in the Otoroshi Admin UI.

You can follow [this guide](/docs/entities/keypairs) to help you to create your first Biscuit Keypair.

2. **Create a Route in Otoroshi**:
- Go to the **Routes** section in the Otoroshi Admin UI.
- Add a new route with the path `/.well-known/biscuit-web-keys`.

3. **Enable Public Key Exposition**:
- Add the `Cloud APIM - Expose Biscuit public keys`plugin to your route.

## Plugin configuration

Public keys are selected for exposition based on the following rules:

1. **Defining Authorized Public Keys** (Optional):
- You can explicitly list authorized public keys in the configuration.
- Only the keys in this list will be exposed.

2. **Leaving the Authorized List Blank**:
- If you do not specify an authorized keys list, **all keys** can be exposed.
- However, each key **must** have the **"Expose this public key"** flag enabled to be included.

## How Public Keys Are Exposed

Once configured, Otoroshi will expose public keys in JSON format at the `/.well-known/biscuit-web-keys` endpoint.

Any client or service that needs to verify Biscuit tokens can retrieve the list of valid public keys from this endpoint.

## Example Public Key Exposition Output

When configured correctly, the system will expose public keys in the following JSON format:

```json
{
"items": [
{
"algorithm": "ed25519",
"key_bytes": "B8453EA97EAF3D6A24FCC63D1317225BE9AAB1ABF26FBEFE8A34FE5BF39BFA00",
"key_id": "biscuit-keypair_6a3a5de9-b2ef-4bae-9422-9d644ec3b419",
"issuer": "Otoroshi"
},
{
"algorithm": "ed25519",
"key_bytes": "294DC8ED8EF8C491DC9632EDDD827F81384325A6C6DEFBC643F6EBCF41D155BA",
"key_id": "biscuit-keypair_82167e67-e820-402f-a564-c4cd1b35832f",
"issuer": "Otoroshi"
}
]
}
```
Original file line number Diff line number Diff line change
Expand Up @@ -38,26 +38,25 @@ class BiscuitAttenuatorPage extends Component {
},
},
"config.checks": {
type: 'array',
props: {
component:
(props) =>
React.createElement(
React.Suspense,
{ fallback: "Loading..." },
React.createElement(LazyCodeInput, {
label: "",
height: "50px",
mode: "prolog",
value: props.itemValue,
onChange: (e) => {
const arr = props.value;
arr[props.idx] = e;
props.onChange(arr);
},
})
)
}
type: "array",
props: {
component: (props) =>
React.createElement(
React.Suspense,
{ fallback: "Loading..." },
React.createElement(LazyCodeInput, {
label: "",
height: "50px",
mode: "prolog",
value: props.itemValue,
onChange: (e) => {
const arr = props.value;
arr[props.idx] = e;
props.onChange(arr);
},
})
),
},
},
tester: {
type: BiscuitAttenuatorTester,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,10 @@ class BiscuitKeyPairPage extends Component {
type: "array",
props: { label: "Tags" },
},
is_public: {
type: "bool",
props: { label: "Expose public key" },
},
keypair_generator: {
type: KeyPairGenerator,
},
Expand Down Expand Up @@ -69,9 +73,11 @@ class BiscuitKeyPairPage extends Component {
"id",
"name",
"description",
">>>Metadata and tags",
">>>Metadata and tags",
"tags",
"metadata",
"<<<Public Key exposition",
"is_public",
"<<<KeyPair parameters",
"keypair_generator",
// "<<< Biscuit playground",
Expand Down Expand Up @@ -113,7 +119,7 @@ class BiscuitKeyPairPage extends Component {
"metadata.updated_at",
],
}),
updateItem: (e) => {
updateItem: (e) => {
if (!e.privKey || !e.pubKey) {
alert("Public key or private key not provided !");
} else {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ class BiscuitRbacPoliciesPage extends Component {
roles: {
type: "object",
props: { label: "List of Roles" },
}
},
};

columns = [
Expand Down Expand Up @@ -81,29 +81,25 @@ class BiscuitRbacPoliciesPage extends Component {
parentProps: this.props,
selfUrl: "extensions/cloud-apim/biscuit/rbac",
defaultTitle: "All Biscuit RBAC Policies",
defaultValue: () => this.client.template(),
defaultValue: () => this.client.template(),
itemName: "Biscuit RBAC Policy",
formSchema: this.formSchema,
formFlow: this.formFlow,
columns: this.columns,
stayAfterSave: true,
fetchTemplate: () => this.client.template(),
fetchItems: (paginationState) => this.client.findAll(),
updateItem: (e) => {
updateItem: (e) => {
if (Object.keys(e.roles).length === 0) {
alert(
"Your roles list seems to be empty."
);
alert("Your roles list seems to be empty.");
} else {
return this.client.update(e);
}
},
deleteItem: this.client.delete,
createItem: (e) => {
createItem: (e) => {
if (Object.keys(e.roles).length === 0) {
alert(
"Your roles list seems to be empty."
);
alert("Your roles list seems to be empty.");
} else {
return this.client.create(e);
}
Expand All @@ -123,4 +119,4 @@ class BiscuitRbacPoliciesPage extends Component {
null
);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -39,20 +39,17 @@ class BiscuitRemoteFactsLoaderPage extends Component {
type: "select",
props: {
label: "HTTP method",
possibleValues: [
'GET',
'POST',
'PUT',
'DELETE',
'PATCH',
].map(v => ({ label: v, value: v }))
possibleValues: ["GET", "POST", "PUT", "DELETE", "PATCH"].map((v) => ({
label: v,
value: v,
})),
},
},
"config.timeout": {
type: "number",
props: {
label: "HTTP timeout",
suffix: 'milliseconds',
suffix: "milliseconds",
},
},
"config.headers": {
Expand Down
Loading

0 comments on commit eae36ea

Please sign in to comment.