Verifiers
Overview
A Biscuit Verifier is a key component in the Eclipse Biscuit token framework, used to validate and enforce additional constraints on an Eclipse Biscuit token.
While tokens inherently carry embedded rules and checks, a verifier allows you to apply context-specific restrictions during token validation without modifying the token itself.
Using a verifier means you don’t need to modify or reissue tokens for every new constraint.
Instead, constraints can be added at runtime when validating the token.
Key Features
- Dynamic Constraint Management: Add new constraints at runtime without altering the original token.
- Enhanced Security: Enforce strict validation policies tailored to specific contexts.
- Extensibility: Easily integrate with various APIs and frameworks.
Common Use Cases
- Limiting token usage to specific timeframes.
- Restricting token access to particular resources.
- Enforcing domain-specific rules dynamically.
Example Configuration
The following JSON configuration defines a Biscuit Verifier with a time constraint:
{
"enabled": true,
"id": "biscuit_verifier_6f5f20a5-2c65-4860-8ad1-7b6495ee03bf",
"keypair_ref": "biscuit-keypair_dev_d25612c6-b4d0-43ed-a711-16b6c09a5155",
"name": "New Biscuit Verifier",
"description": "New Biscuit Verifier",
"strict": true,
"tags": [],
"config": {
"checks": [],
"facts": [
"operation(\"read\")"
],
"resources": [
"/folder1/file1"
],
"rules": [],
"policies": [],
"rbac_refs": [],
"revoked_ids": [],
"remote_facts_refs": []
},
"extractor": {
"extractor_type": "header",
"extractor_name": "Authorization"
}
}
Explanation of Fields
Item | Type | Default value | Explanation |
---|---|---|---|
id | String | Unique identifier for the verifier entity | |
enabled | Boolean | true | Indicates if the verifier is active |
keypair_ref | String | Reference to the keypair entity used for token verification | |
name | String | New Biscuit Verifier | Human-readable name for the verifier. |
description | String | New Biscuit Verifier | Description of the verifier’s purpose. |
remote_facts_refs | String | Reference to the Remote Facts entity to load external facts |
Get a Biscuit Verifier Entity template with Otoroshi's API
curl -X GET \
-H 'Content-Type: application/json' \
-H 'Otoroshi-Client-Id: admin-api-apikey-id' \
-H 'Otoroshi-Client-Secret: admin-api-apikey-secret' \
'http://otoroshi-api.oto.tools:8080/apis/biscuit.extensions.cloud-apim.com/v1/biscuit-verifiers/_template'
Result :
{
"enabled": true,
"id": "biscuit-verifier_eaa118fe-c59c-4c22-b446-cb415c33c887",
"keypair_ref": "",
"name": "New biscuit verifier",
"description": "New biscuit verifier",
"metadata": {},
"strict": true,
"tags": [],
"config": {
"checks": [],
"facts": [],
"resources": [],
"rules": [],
"policies": [],
"rbac_refs": [],
"revoked_ids": [],
"remote_facts_refs": []
},
"extractor": {
"extractor_type": "header",
"extractor_name": "Authorization"
}
}
Create a Biscuit Verifier Entity from Command Line
You can create a Biscuit Verifier using the Otoroshi API with the following curl
command:
curl -X POST -H 'Content-Type: application/json' \
'http://otoroshi-api.oto.tools:8080/apis/biscuit.extensions.cloud-apim.com/v1/biscuit-verifiers' \
-u admin-api-apikey-id:admin-api-apikey-secret \
-d '{
"enabled": true,
"id": "biscuit_verifier_6f5f20a5-2c65-4860-8ad1-7b6495ee03bf",
"keypair_ref": "biscuit-keypair_dev_d25612c6-b4d0-43ed-a711-16b6c09a5155",
"name": "New Biscuit Verifier",
"description": "New Biscuit Verifier",
"strict": true,
"tags": [],
"config": {
"checks": [],
"facts": [
"operation(\"read\")"
],
"resources": [
"/folder1/file1"
],
"rules": [],
"policies": [],
"rbac_refs": [],
"revoked_ids": [],
"remote_facts_refs": []
},
"extractor": {
"extractor_type": "header",
"extractor_name": "Authorization"
}
}'
Bulk creation
curl -X POST -H 'Content-Type: application/x-ndjson' \
'http://otoroshi-api.oto.tools:8080/apis/biscuit.extensions.cloud-apim.com/v1/biscuit-verifiers/_bulk' \
-u admin-api-apikey-id:admin-api-apikey-secret \
-d '{"enabled":true,"id":"verifier_bulk_1","keypair_ref":"biscuit_keypair_e42033bc-f181-485f-857d-576e4728f6f9","name":"Biscuit Verifier FROM CURL BULK 1","description":"A Biscuit Verifier created from Otoroshi API","strict":true,"tags":[],"config.checks":["check if time($date), $date <= 2024-12-30T19:00:10Z;"],"config.facts":[],"config.resources":[],"config.rules":[],"config.revocation_ids":[],"kind":"biscuit.extensions.cloud-apim.com/BiscuitVerifier"}
{"enabled":true,"id":"verifier_bulk_2","keypair_ref":"biscuit_keypair_e42033bc-f181-485f-857d-576e4728f6f9","name":"Biscuit Verifier FROM CURL BULK 2","description":"A Biscuit Verifier created from Otoroshi API","strict":true,"tags":[],"config.checks":["check if time($date), $date <= 2024-12-30T19:00:10Z;"],"config.facts":[],"config.resources":[],"config.rules":[],"config.revocation_ids":[],"kind":"biscuit.extensions.cloud-apim.com/BiscuitVerifier"}'
Response
{"status":201,"created":true,"id":"verifier_bulk_1","id_field":"id"}
{"status":201,"created":true,"id":"verifier_bulk_2","id_field":"id"}
Configuration Examples
Rules
Rules are logical expressions used to define conditions under which certain actions are authorized. They can combine facts, predicates, and other rules to evaluate permissions.
Example Rule
The following rule determines whether a user is allowed to perform an operation on a resource:
is_allowed($user, $res, $op) <-
user($user), // Declares the user
resource($res), // Declares the resource
operation($op), // Declares the operation
right($user, $res, $op); // Verifies the user has the necessary rights
In this example:
user($user)
identifies the user.resource($res)
identifies the resource being accessed.operation($op)
specifies the action (e.g., read, write).right($user, $res, $op)
asserts that the user has the permission for the operation on the resource.
Facts
Facts are data points or assertions stored in the Biscuit token. They are used as inputs to evaluate the rules. For example:
user("alice");
resource("file1");
operation("read");
right("alice", "file1", "read");
These facts state that:
- Alice is the user.
- The resource is "file1".
- The operation is "read".
- Alice has the right to perform the read operation on file1.
Policies
Policies are used to define the decision logic for allowing or denying access. Biscuit tokens support allow
and deny
policies to control access.
Example Policy
The following policy allows access if the is_allowed
rule evaluates to true:
allow if is_allowed($user, $resource, $op);
This policy specifies that:
- Access is granted (
allow
) if theis_allowed
rule matches.
Combining Policies
Policies can also include deny conditions, such as:
deny if user($user), resource($res), operation($op), not right($user, $res, $op);
This policy denies access if:
- A user, resource, and operation are defined.
- The user does not have the corresponding right for the resource and operation.
Contextual Restrictions
Biscuit tokens support additional contextual restrictions using caveats. Caveats allow tokens to impose extra conditions that must be satisfied for access to be granted.
Example of Caveats
To restrict access to a specific time range:
time($t), $t <= 1672531200, $t >= 1672444800;
Here:
$t
represents the current time.- Access is allowed only if the current time falls between the specified timestamps.
Example with IP Restriction
To restrict access based on IP address:
ip("192.168.1.1");
Access is allowed only if the IP matches 192.168.1.1
.
Advanced Examples
Hierarchical Rights
Defining a hierarchy where admin users have access to all resources and operations:
right($user, $res, $op) <- role($user, "admin");
Read-Only Role
Defining a "read-only" role:
right($user, $res, "read") <- role($user, "read-only");
Resource-Specific Rights
Granting a user specific rights on a specific resource:
right("bob", "file2", "write");