PHP bindings for Biscuit, a bearer token supporting offline attenuation, decentralized verification, and powerful authorization policies.
- Biscuit Website - Documentation and examples
- Biscuit Specification
- Biscuit Rust - Technical details
cargo-php- PHP >= 8.1 with
php-devinstalled - Rust
- Clang
Pre-built binaries are available for Linux x86_64 across multiple PHP versions, with both Thread-Safe (TS) and Non-Thread-Safe (NTS) variants. Download the appropriate binary for your PHP version and thread safety from the latest release.
# Download binary for your PHP version and thread safety
# Replace 8.3 with your version and ts/nts based on your thread safety
wget https://github.com/ptondereau/biscuit-php/releases/latest/download/ext_biscuit_php-linux-x86_64-php8.3-nts.so
# Verify checksum
wget https://github.com/ptondereau/biscuit-php/releases/latest/download/ext_biscuit_php-linux-x86_64-php8.3-nts.so.sha256
sha256sum -c ext_biscuit_php-linux-x86_64-php8.3-nts.so.sha256
# Move to PHP extension directory (adjust path for your system)
sudo mv ext_biscuit_php-linux-x86_64-php8.3-nts.so /usr/lib/php/$(php -r 'echo PHP_MAJOR_VERSION.".".PHP_MINOR_VERSION;')/
# Enable the extension
echo "extension=ext_biscuit_php-linux-x86_64-php8.3-nts.so" | sudo tee /etc/php/$(php -r 'echo PHP_MAJOR_VERSION.".".PHP_MINOR_VERSION;')/mods-available/biscuit.ini
sudo phpenmod biscuit
# Verify installation
php -m | grep biscuitWe support PIE installation:
pie install ptondereau/biscuit-phpand you can add in your composer.json:
{
// ...
"ext-biscuit": "*",
// ...
}If pre-built binaries are not available for your platform:
# Clone the repository
git clone https://github.com/ptondereau/biscuit-php.git
cd biscuit-php
# Install dependencies
composer install
# Build the extension
cargo build --release
# Load the extension
php -dextension=target/release/libext_biscuit_php.so -m | grep biscuitWe're exposing PHP stubs for IDE integration
composer require ptondereau/ext-biscuit-php<?php
use Biscuit\Auth\{BiscuitBuilder, KeyPair, AuthorizerBuilder};
// Generate a keypair
$root = new KeyPair();
// Create a biscuit token
$builder = new BiscuitBuilder();
$builder->addCode('user("alice"); resource("file1")');
$biscuit = $builder->build($root->private());
// Serialize to base64
$token = $biscuit->toBase64();
// Parse and authorize
$parsed = Biscuit::fromBase64($token, $root->public());
$authBuilder = new AuthorizerBuilder();
$authBuilder->addCode('allow if user("alice"), resource("file1")');
$authorizer = $authBuilder->build($parsed);
// Check authorization
$policy = $authorizer->authorize();
echo $policy === 0 ? "Authorized!" : "Denied!";// Create biscuit
$biscuit = $builder->build($rootKey);
// Third-party attestation
$thirdPartyKey = new KeyPair();
$request = $biscuit->thirdPartyRequest();
$externalBlock = new BlockBuilder();
$externalBlock->addCode('external_fact("verified");');
$signedBlock = $request->createBlock($thirdPartyKey->private(), $externalBlock);
$biscuitWithAttestation = $biscuit->appendThirdParty(
$thirdPartyKey->public(),
$signedBlock
);$authorizer = $authBuilder->build($biscuit);
$rule = new Rule('users($id) <- user($id);');
$facts = $authorizer->query($rule);
foreach ($facts as $fact) {
echo "Found: {$fact->name()}\n";
}// Save authorizer state
$snapshot = $authorizer->base64Snapshot();
// Restore later
$restored = Authorizer::fromBase64Snapshot($snapshot);
$policy = $restored->authorize();$pem = "-----BEGIN PRIVATE KEY-----\n...\n-----END PRIVATE KEY-----";
$privateKey = PrivateKey::fromPem($pem);
$keyPair = KeyPair::fromPrivateKey($privateKey);use Biscuit\Auth\Algorithm;
// Ed25519 is the default algorithm (recommended)
$keypair1 = new KeyPair(); // Uses Ed25519
$keypair2 = KeyPair::newWithAlgorithm(); // Uses Ed25519 by default
// Explicitly use Secp256r1
$keypair3 = KeyPair::newWithAlgorithm(Algorithm::Secp256r1);
// Key import defaults to Ed25519
$publicKey = PublicKey::fromBytes($bytes); // Defaults to Ed25519
$publicKey = PublicKey::fromBytes($bytes, Algorithm::Ed25519); // Explicit Ed25519
$publicKey = PublicKey::fromBytes($bytes, Algorithm::Secp256r1); // Explicit Secp256r1cargo build
php \
-dextension=target/debug/libext_biscuit_php.so \
vendor/bin/phpunitWe're using Mago as code-style formatter for PHP code
composer install
cargo build
php \
-dextension=target/debug/libext_biscuit_php.so \
vendor/bin/mago lint // and formatcargo build
php \
-dextension=target/debug/libext_biscuit_php.so \
php-extension-stub-generator.phar dump-files ext-biscuit-php stubsContributions are welcome! Please:
- Add tests for new features
- Update documentation
- Ensure all tests pass
Licensed under Apache License, Version 2.0.