### Install biscuit-pulsar and Dependencies Source: https://context7.com/clevercloud/biscuit-pulsar/llms.txt Provides instructions for installing the biscuit-pulsar library and its dependencies into the Pulsar broker's lib directory. ```bash #!/bin/bash ``` -------------------------------- ### Download and Install Pulsar Dependencies Source: https://context7.com/clevercloud/biscuit-pulsar/llms.txt Download necessary JAR files for Biscuit Pulsar integration into the Pulsar lib folder. Ensure PULSAR_HOME and VERSION variables are set correctly. ```bash PULSAR_HOME=/path/to/pulsar VERSION=3.7.1 wget -P "${PULSAR_HOME}/lib" "https://repo1.maven.org/maven2/net/i2p/crypto/eddsa/0.3.0/eddsa-0.3.0.jar" wget -P "${PULSAR_HOME}/lib" "https://repo1.maven.org/maven2/io/vavr/vavr/0.10.3/vavr-0.10.3.jar" wget -P "${PULSAR_HOME}/lib" "https://repo1.maven.org/maven2/com/google/protobuf/protobuf-java/3.25.0/protobuf-java-3.25.0.jar" wget -P "${PULSAR_HOME}/lib" "https://repo1.maven.org/maven2/org/biscuitsec/biscuit/4.0.1/biscuit-4.0.1.jar" wget -P "${PULSAR_HOME}/lib" "https://repo1.maven.org/maven2/com/clever-cloud/biscuit-pulsar/${VERSION}/biscuit-pulsar-${VERSION}.jar" ``` -------------------------------- ### Build and test project Source: https://github.com/clevercloud/biscuit-pulsar/blob/master/README.md Maven commands for building the project with or without running tests. ```bash # run all tests and build mvn clean install # build without tests mvn clean install -Dmaven.test.skip=true ``` -------------------------------- ### Initialize Pulsar client with Biscuit Source: https://github.com/clevercloud/biscuit-pulsar/blob/master/README.md Java code to instantiate a Pulsar client using a Biscuit or JWT token. ```java PulsarClient client = PulsarClient.builder() .authentication(new AuthenticationToken("")) .serviceUrl("pulsar://localhost:6650") .build(); ``` -------------------------------- ### Download dependencies for Pulsar Source: https://github.com/clevercloud/biscuit-pulsar/blob/master/README.md Script to download required JAR files into the Pulsar library directory. ```bash #!/bin/bash wget -P "pulsar/lib" "https://repo1.maven.org/maven2/net/i2p/crypto/eddsa/0.3.0/eddsa-0.3.0.jar" wget -P "pulsar/lib" "https://repo1.maven.org/maven2/io/vavr/vavr/0.10.3/vavr-0.10.3.jar" wget -P "pulsar/lib" "https://repo1.maven.org/maven2/com/google/protobuf/protobuf-java/3.25.0/protobuf-java-3.25.0.jar" wget -P "pulsar/lib" "https://repo1.maven.org/maven2/com/clever-cloud/biscuit-java//biscuit-java-.jar" wget -P "pulsar/lib" "https://repo1.maven.org/maven2/com/clever-cloud/biscuit-pulsar//biscuit-pulsar-.jar" ``` -------------------------------- ### Configure Biscuit Token Revocation List Source: https://context7.com/clevercloud/biscuit-pulsar/llms.txt Specifies how to create a revocation list file for Biscuit tokens. Revoked tokens will fail authentication. ```bash # Create revocation list file at /etc/biscuit/revocation_list.hex.conf # Each line contains a hex-encoded revocation identifier # Example revocation_list.hex.conf: a1b2c3d4e5f6789012345678901234567890123456789012345678901234567890 b2c3d4e5f67890123456789012345678901234567890123456789012345678901 ``` -------------------------------- ### Inject public root key into configuration Source: https://github.com/clevercloud/biscuit-pulsar/blob/master/README.md Shell script to replace the placeholder key in Pulsar configuration files. ```bash #!/bin/bash sed -i -e "s/@@BISCUIT_PUBLIC_ROOT_KEY@@/$1/" broker.conf sed -i -e "s/@@BISCUIT_PUBLIC_ROOT_KEY@@/$1/" proxy.conf sed -i -e "s/@@BISCUIT_PUBLIC_ROOT_KEY@@/$1/" standalone.conf ``` -------------------------------- ### Attenuate Biscuit Tokens for Restricted Permissions Source: https://context7.com/clevercloud/biscuit-pulsar/llms.txt Demonstrates creating a root token and applying successive blocks to restrict access by namespace, operation type, and topic prefix. ```java import org.biscuitsec.biscuit.token.Biscuit; import org.biscuitsec.biscuit.token.builder.Block; import org.apache.pulsar.common.naming.TopicName; import org.apache.pulsar.common.policies.data.TopicOperation; import static com.clevercloud.biscuitpulsar.formatter.BiscuitFormatter.*; // Start with a root token that has full admin rights Block rootBlock = new Block(); rootBlock.add_fact(adminFact); Biscuit rootBiscuit = Biscuit.make(rng, root, rootBlock.build(symbols)); // Attenuate to limit access to a specific namespace Block nsLimitBlock = rootBiscuit.create_block(); nsLimitBlock.add_check("check if namespace(\"tenantTest\",\"namespaceTest\") or topic(\"tenantTest\",\"namespaceTest\", $topic)"); Biscuit nsLimitedToken = rootBiscuit.attenuate(rng, root, nsLimitBlock.build(symbols)); // Further attenuate to restrict to produce operation only Block produceOnlyBlock = nsLimitedToken.create_block(); produceOnlyBlock.add_check("check if topic(\"tenantTest\",\"namespaceTest\", $topic), topic_operation(\"produce\")"); Biscuit produceOnlyToken = nsLimitedToken.attenuate(rng, root, produceOnlyBlock.build(symbols)); // Further attenuate to limit to topics with a specific prefix String PREFIX = "events-"; Block prefixBlock = produceOnlyToken.create_block(); prefixBlock.add_check("check if topic(\"tenantTest\",\"namespaceTest\", $topic), $topic.starts_with(\"" + PREFIX + "\")"); Biscuit prefixLimitedToken = produceOnlyToken.attenuate(rng, root, prefixBlock.build(symbols)); // The final token can only produce to topics like: // tenantTest/namespaceTest/events-orders // tenantTest/namespaceTest/events-users ``` -------------------------------- ### Create Subscription-Based Authorization Token Source: https://context7.com/clevercloud/biscuit-pulsar/llms.txt Generates a Biscuit token that permits consumption only on a specific subscription. Requires setting up topic and subscription details. ```java import org.biscuitsec.biscuit.token.Biscuit; import org.biscuitsec.biscuit.token.builder.Block; import org.apache.pulsar.common.naming.TopicName; import org.apache.pulsar.common.policies.data.TopicOperation; import static com.clevercloud.biscuitpulsar.formatter.BiscuitFormatter.*; // Create token that allows consume only on a specific subscription String tenant = "tenantTest"; String namespace = "namespaceTest"; String topic = "topicTest"; String subscription = "mySubscription"; Block block = new Block(); block.add_fact(adminFact); block.add_check(topicOperationCheck( TopicName.get(tenant + "/" + namespace + "/" + topic), TopicOperation.CONSUME, subscription // Subscription constraint )); Biscuit subscriptionToken = Biscuit.make(rng, root, block.build(symbols)); ``` ```java // Authorization check with subscription context AuthenticationDataSource authData = new AuthenticationDataSource() { @Override public boolean hasSubscription() { return true; } @Override public String getSubscription() { return "mySubscription"; } }; // This will succeed - correct subscription boolean canConsume = authorizationProvider .allowTopicOperationAsync( TopicName.get(tenant + "/" + namespace + "/" + topic), authedBiscuit, TopicOperation.CONSUME, authData ).get(); // Returns: true ``` ```java // This will fail - wrong subscription authData = new AuthenticationDataSource() { @Override public String getSubscription() { return "wrongSubscription"; } }; canConsume = authorizationProvider .allowTopicOperationAsync( TopicName.get(tenant + "/" + namespace + "/" + topic), authedBiscuit, TopicOperation.CONSUME, authData ).get(); // Returns: false ``` -------------------------------- ### Configure Pulsar authentication and authorization Source: https://github.com/clevercloud/biscuit-pulsar/blob/master/README.md Configuration settings for broker, proxy, or standalone Pulsar nodes to enable Biscuit security providers. ```bash # Enable authentication authenticationEnabled=true # Autentication provider name list, which is comma separated list of class names authenticationProviders=com.clevercloud.biscuitpulsar.AuthenticationProviderBiscuit # Enforce authorization authorizationEnabled=true # Authorization provider fully qualified class-name authorizationProvider=com.clevercloud.biscuitpulsar.AuthorizationProviderBiscuit ### --- Biscuit Authentication Provider --- ### biscuitPublicRootKey=@@BISCUIT_PUBLIC_ROOT_KEY@@ # support JWT side by side with Biscuit for AuthenticationToken biscuitSupportJWT=true|false # biscuit verify run limits before TimeOut biscuitRunLimitsMaxFacts=1000 biscuitRunLimitsMaxIterations=100 biscuitRunLimitsMaxTimeMillis=30 ``` -------------------------------- ### Implement Client-Side Authentication Source: https://context7.com/clevercloud/biscuit-pulsar/llms.txt Use the AuthenticationBiscuit class to connect to Pulsar brokers using various token loading strategies. ```java import com.clevercloud.biscuitpulsar.AuthenticationBiscuit; import org.apache.pulsar.client.api.PulsarClient; import org.apache.pulsar.client.api.AuthenticationToken; // Option 1: Using AuthenticationToken with base64url-encoded Biscuit String biscuitB64 = "EnYKDBgDIggKBggEEgIYDRIkCAASI..."; PulsarClient client = PulsarClient.builder() .authentication(new AuthenticationToken(biscuitB64)) .serviceUrl("pulsar://localhost:6650") .build(); // Option 2: Using AuthenticationBiscuit directly with token string AuthenticationBiscuit auth = new AuthenticationBiscuit(biscuitB64); PulsarClient client2 = PulsarClient.builder() .authentication(auth) .serviceUrl("pulsar://localhost:6650") .build(); // Option 3: Load Biscuit from file AuthenticationBiscuit authFromFile = new AuthenticationBiscuit(); authFromFile.configure("file:///path/to/biscuit.token"); // Option 4: Using a supplier for dynamic token refresh AuthenticationBiscuit authDynamic = new AuthenticationBiscuit(() -> { // Fetch fresh token from secure storage return fetchBiscuitToken(); }); ``` -------------------------------- ### Generate Biscuit Tokens with Access Rights Source: https://context7.com/clevercloud/biscuit-pulsar/llms.txt Create and sign Biscuit tokens server-side to grant specific topic-level permissions. ```java import org.biscuitsec.biscuit.crypto.KeyPair; import org.biscuitsec.biscuit.datalog.SymbolTable; import org.biscuitsec.biscuit.token.Biscuit; import org.biscuitsec.biscuit.token.builder.Block; import static com.clevercloud.biscuitpulsar.formatter.BiscuitFormatter.*; import java.security.SecureRandom; // Generate root key pair (store private key securely) SecureRandom rng = new SecureRandom(); KeyPair root = new KeyPair(rng); SymbolTable symbols = Biscuit.default_symbol_table(); // Create a super-user token with full admin rights Block adminBlock = new Block(); adminBlock.add_fact("right(\"admin\")"); Biscuit superUserToken = Biscuit.make(rng, root, adminBlock.build(symbols)); String superUserB64 = superUserToken.serialize_b64url(); // Create a token for produce-only access to a specific topic String tenant = "myTenant"; String namespace = "myNamespace"; String topic = "myTopic"; Block produceBlock = new Block(); produceBlock.add_fact(adminFact); produceBlock.add_check(topicOperationCheck( TopicName.get(tenant + "/" + namespace + "/" + topic), TopicOperation.PRODUCE )); Biscuit produceOnlyToken = Biscuit.make(rng, root, produceBlock.build(symbols)); // Token output (base64url encoded): // EnYKDBgDIggKBggEEgIYDRIkCAASIOH... ``` -------------------------------- ### Authorize Pulsar Operations with AuthorizationProviderBiscuit Source: https://context7.com/clevercloud/biscuit-pulsar/llms.txt Shows how to use AuthorizationProviderBiscuit to verify topic and namespace permissions, as well as superuser status. ```java import com.clevercloud.biscuitpulsar.AuthorizationProviderBiscuit; import org.apache.pulsar.common.naming.TopicName; import org.apache.pulsar.common.naming.NamespaceName; import org.apache.pulsar.common.policies.data.TopicOperation; import org.apache.pulsar.common.policies.data.NamespaceOperation; AuthorizationProviderBiscuit authorizationProvider = new AuthorizationProviderBiscuit(); // Check topic produce permission boolean canProduce = authorizationProvider .allowTopicOperationAsync( TopicName.get("tenant/namespace/topic"), authedBiscuit, TopicOperation.PRODUCE, null ).get(); // Returns: true if Biscuit authorizes produce, false otherwise // Check topic consume permission boolean canConsume = authorizationProvider .allowTopicOperationAsync( TopicName.get("tenant/namespace/topic"), authedBiscuit, TopicOperation.CONSUME, null ).get(); // Check namespace operation (create topic) boolean canCreateTopic = authorizationProvider .allowNamespaceOperationAsync( NamespaceName.get("tenant/namespace"), authedBiscuit, NamespaceOperation.CREATE_TOPIC, null ).get(); // Check super user status boolean isSuperUser = authorizationProvider .isSuperUser(authedBiscuit, null, serviceConfiguration) .get(); ``` -------------------------------- ### BiscuitFormatter Authorization Rule Helpers Source: https://context7.com/clevercloud/biscuit-pulsar/llms.txt Provides utility methods for generating Biscuit datalog facts and checks for Pulsar authorization, including topic, namespace, and operation rules. ```java import static com.clevercloud.biscuitpulsar.formatter.BiscuitFormatter.*; import org.apache.pulsar.common.naming.TopicName; import org.apache.pulsar.common.naming.NamespaceName; import org.apache.pulsar.common.policies.data.TopicOperation; import org.apache.pulsar.common.policies.data.NamespaceOperation; import org.apache.pulsar.common.policies.data.PolicyName; import org.apache.pulsar.common.policies.data.PolicyOperation; // Create topic facts String topicFact = topicFact(TopicName.get("tenant/namespace/topic")); // Output: topic("tenant","namespace","topic") ``` ```java // Create namespace facts String nsFact = namespaceFact(NamespaceName.get("tenant/namespace")); // Output: namespace("tenant","namespace") ``` ```java // Create operation facts String opFact = topicOperationFact(TopicOperation.PRODUCE); // Output: topic_operation("produce") ``` ```java // Create topic operation checks String check = topicOperationCheck( TopicName.get("tenant/namespace/topic"), TopicOperation.CONSUME ); // Output: check if topic("tenant","namespace","topic"), topic_operation("consume") ``` ```java // Create namespace operation checks String nsOpFact = namespaceOperationFact(NamespaceOperation.CREATE_TOPIC); // Output: namespace_operation("create_topic") ``` ```java // Policy operation facts String policyFact = namespacePolicyOperationFact(PolicyName.TTL, PolicyOperation.WRITE); // Output: namespace_operation("ttl_write") ``` ```java // Admin fact for super user access String admin = adminFact; // Output: right("admin") ``` ```java // Admin check String adminCheck = BiscuitFormatter.adminCheck; // Output: check if right("admin") ``` -------------------------------- ### Configure Pulsar Broker for Biscuit Source: https://context7.com/clevercloud/biscuit-pulsar/llms.txt Set these properties in your broker configuration files to enable the Biscuit authentication and authorization providers. ```properties // Broker configuration (broker.conf, proxy.conf, or standalone.conf) // Enable authentication authenticationEnabled=true // Set authentication provider authenticationProviders=com.clevercloud.biscuitpulsar.AuthenticationProviderBiscuit // Enable authorization authorizationEnabled=true authorizationProvider=com.clevercloud.biscuitpulsar.AuthorizationProviderBiscuit // Configure Biscuit root public key (hex-encoded Ed25519 public key) biscuitPublicRootKey=005248AE3870664EFC914A287BD2DB70626316E2CD004FA138837E8430D9A5CF // Optional: Enable JWT fallback for hybrid authentication biscuitSupportJWT=true // Configure authorization run limits biscuitRunLimitsMaxFacts=1000 biscuitRunLimitsMaxIterations=100 biscuitRunLimitsMaxTimeMillis=30 ``` -------------------------------- ### Set project version for release Source: https://github.com/clevercloud/biscuit-pulsar/blob/master/README.md Maven commands to update the project version during the release process. ```bash mvn versions:set -DnewVersion= ``` ```bash mvn versions:set -DnewVersion= ``` -------------------------------- ### Retrieve and Format Biscuit Token Revocation Identifiers Source: https://context7.com/clevercloud/biscuit-pulsar/llms.txt Demonstrates how to extract revocation identifiers from a Biscuit token and format them into hexadecimal strings for inclusion in a revocation list. ```java import org.biscuitsec.biscuit.token.Biscuit; import org.biscuitsec.biscuit.token.RevocationIdentifier; // Get revocation identifiers from a Biscuit token Biscuit biscuit = Biscuit.from_b64url(tokenB64, rootPublicKey); List revocationIds = biscuit.revocation_identifiers(); // Convert to hex for adding to revocation list for (RevocationIdentifier id : revocationIds) { String hexId = bytesToHex(id.serialize()); System.out.println(hexId); // Add this to /etc/biscuit/revocation_list.hex.conf to revoke } // Authentication will fail for revoked tokens // AuthenticationException: "Biscuit has been revoked." ``` -------------------------------- ### Maven Dependency for Biscuit Pulsar Source: https://context7.com/clevercloud/biscuit-pulsar/llms.txt Include this Maven dependency in your client application to use Biscuit Pulsar. ```xml com.clever-cloud biscuit-pulsar 3.7.1 ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.