# Create consent by email Source: https://docs.databunker.org/oss/api/consent/create-consent-by-email /oss/api/openapi.yml post /v1/consent/email/{email}/{brief} Stores consent for a user identified by email # Create consent by login Source: https://docs.databunker.org/oss/api/consent/create-consent-by-login /oss/api/openapi.yml post /v1/consent/login/{login}/{brief} Stores consent for a user identified by login # Create consent by phone Source: https://docs.databunker.org/oss/api/consent/create-consent-by-phone /oss/api/openapi.yml post /v1/consent/phone/{phone}/{brief} Stores consent for a user identified by phone # Create consent by user token Source: https://docs.databunker.org/oss/api/consent/create-consent-by-user-token /oss/api/openapi.yml post /v1/consent/token/{token}/{brief} Stores user consent. The `brief` parameter is a unique consent identifier per user. Allowed characters: [a-z0-9-], max 64 characters. # Get consent by email Source: https://docs.databunker.org/oss/api/consent/get-consent-by-email /oss/api/openapi.yml get /v1/consent/email/{email}/{brief} Retrieves consent record for a user identified by email # Get consent by login Source: https://docs.databunker.org/oss/api/consent/get-consent-by-login /oss/api/openapi.yml get /v1/consent/login/{login}/{brief} Retrieves consent record for a user identified by login # Get consent by phone Source: https://docs.databunker.org/oss/api/consent/get-consent-by-phone /oss/api/openapi.yml get /v1/consent/phone/{phone}/{brief} Retrieves consent record for a user identified by phone # Get consent by user token Source: https://docs.databunker.org/oss/api/consent/get-consent-by-user-token /oss/api/openapi.yml get /v1/consent/token/{token}/{brief} Retrieves consent record for a user # List all consents by email Source: https://docs.databunker.org/oss/api/consent/list-all-consents-by-email /oss/api/openapi.yml get /v1/consent/email/{email} Returns all consent records for a user identified by email # List all consents by login Source: https://docs.databunker.org/oss/api/consent/list-all-consents-by-login /oss/api/openapi.yml get /v1/consent/login/{login} Returns all consent records for a user identified by login # List all consents by phone Source: https://docs.databunker.org/oss/api/consent/list-all-consents-by-phone /oss/api/openapi.yml get /v1/consent/phone/{phone} Returns all consent records for a user identified by phone # List all consents by user token Source: https://docs.databunker.org/oss/api/consent/list-all-consents-by-user-token /oss/api/openapi.yml get /v1/consent/token/{token} Returns all consent records for a user # Withdraw consent by email Source: https://docs.databunker.org/oss/api/consent/withdraw-consent-by-email /oss/api/openapi.yml delete /v1/consent/email/{email}/{brief} Withdraws consent for a user identified by email # Withdraw consent by login Source: https://docs.databunker.org/oss/api/consent/withdraw-consent-by-login /oss/api/openapi.yml delete /v1/consent/login/{login}/{brief} Withdraws consent for a user identified by login # Withdraw consent by phone Source: https://docs.databunker.org/oss/api/consent/withdraw-consent-by-phone /oss/api/openapi.yml delete /v1/consent/phone/{phone}/{brief} Withdraws consent for a user identified by phone # Withdraw consent by user token Source: https://docs.databunker.org/oss/api/consent/withdraw-consent-by-user-token /oss/api/openapi.yml delete /v1/consent/token/{token}/{brief} Withdraws user consent (GDPR compliance) # Cancel user expiration Source: https://docs.databunker.org/oss/api/expiration/cancel-user-expiration /oss/api/openapi.yml post /v1/exp/cancel/{token} Cancels user account expiration. Requires admin or user token. # Delete expired user data Source: https://docs.databunker.org/oss/api/expiration/delete-expired-user-data /oss/api/openapi.yml get /v1/exp/delete/{exptoken} Confirms deletion of expired user data. This link works in the browser without authentication. # Get expiration status Source: https://docs.databunker.org/oss/api/expiration/get-expiration-status /oss/api/openapi.yml get /v1/exp/status/{token} Retrieves user expiration status. Requires admin or user token. # Retain user data Source: https://docs.databunker.org/oss/api/expiration/retain-user-data /oss/api/openapi.yml get /v1/exp/retain/{exptoken} Cancels expiration and retains user data. This link works in the browser without authentication. # Start user expiration flow Source: https://docs.databunker.org/oss/api/expiration/start-user-expiration-flow /oss/api/openapi.yml post /v1/exp/start/{token} Triggers the user expiration flow for data minimization compliance. Returns an expiration token that can be used to create retention/deletion links. # API Overview Source: https://docs.databunker.org/oss/api/overview Databunker is a super-fast, open-source vault built with Go for secure storage of sensitive personal records. ## Authentication All API requests require authentication using the `X-Bunker-Token` header. This token is your root access token. ## Content Types The API supports the following content types for POST and PUT requests: * `application/json` * `application/x-www-form-urlencoded` ## User Tokens Keep the user `{token}` generated by Databunker private, as it serves as an additional user identifier. Under GDPR, this user token is referred to as a pseudonymized identity. For more details, visit: [https://databunker.org/](https://databunker.org/) # Create session by email Source: https://docs.databunker.org/oss/api/session/create-session-by-email /oss/api/openapi.yml post /v1/session/email/{email} Creates a new session for a user identified by email # Create session by login Source: https://docs.databunker.org/oss/api/session/create-session-by-login /oss/api/openapi.yml post /v1/session/login/{login} Creates a new session for a user identified by login # Create session by phone Source: https://docs.databunker.org/oss/api/session/create-session-by-phone /oss/api/openapi.yml post /v1/session/phone/{phone} Creates a new session for a user identified by phone # Create session by user token Source: https://docs.databunker.org/oss/api/session/create-session-by-user-token /oss/api/openapi.yml post /v1/session/token/{token} Creates a new user session and returns a session token. Sessions can have an expiration TTL specified in the request. # Delete session Source: https://docs.databunker.org/oss/api/session/delete-session /oss/api/openapi.yml delete /v1/session/session/{session} Deletes a session by session token # Get session data Source: https://docs.databunker.org/oss/api/session/get-session-data /oss/api/openapi.yml get /v1/session/session/{session} Retrieves session data by session token # List sessions by email Source: https://docs.databunker.org/oss/api/session/list-sessions-by-email /oss/api/openapi.yml get /v1/session/email/{email} Returns all session records for a user identified by email # List sessions by login Source: https://docs.databunker.org/oss/api/session/list-sessions-by-login /oss/api/openapi.yml get /v1/session/login/{login} Returns all session records for a user identified by login # List sessions by phone Source: https://docs.databunker.org/oss/api/session/list-sessions-by-phone /oss/api/openapi.yml get /v1/session/phone/{phone} Returns all session records for a user identified by phone # List sessions by user token Source: https://docs.databunker.org/oss/api/session/list-sessions-by-user-token /oss/api/openapi.yml get /v1/session/token/{token} Returns an array of all session records for a user # Backup database Source: https://docs.databunker.org/oss/api/system/backup-database /oss/api/openapi.yml get /v1/sys/backup Dumps the internal database in SQL format (SQLite only). Requires root token authentication. # Create or update user app record by email Source: https://docs.databunker.org/oss/api/user-app/create-or-update-user-app-record-by-email /oss/api/openapi.yml post /v1/userapp/email/{email}/{appname} Stores app-specific data for a user identified by email # Create or update user app record by login Source: https://docs.databunker.org/oss/api/user-app/create-or-update-user-app-record-by-login /oss/api/openapi.yml post /v1/userapp/login/{login}/{appname} Stores app-specific data for a user identified by login # Create or update user app record by phone Source: https://docs.databunker.org/oss/api/user-app/create-or-update-user-app-record-by-phone /oss/api/openapi.yml post /v1/userapp/phone/{phone}/{appname} Stores app-specific data for a user identified by phone # Create or update user app record by token Source: https://docs.databunker.org/oss/api/user-app/create-or-update-user-app-record-by-token /oss/api/openapi.yml post /v1/userapp/token/{token}/{appname} Stores additional information about a user for a specific application. This is useful for storing app-specific data (e.g., shipping info) separately from profile data. Submitting multiple times overwrites the previous value. # Delete user app record by email Source: https://docs.databunker.org/oss/api/user-app/delete-user-app-record-by-email /oss/api/openapi.yml delete /v1/userapp/email/{email}/{appname} Removes app-specific data for a user identified by email # Delete user app record by login Source: https://docs.databunker.org/oss/api/user-app/delete-user-app-record-by-login /oss/api/openapi.yml delete /v1/userapp/login/{login}/{appname} Removes app-specific data for a user identified by login # Delete user app record by phone Source: https://docs.databunker.org/oss/api/user-app/delete-user-app-record-by-phone /oss/api/openapi.yml delete /v1/userapp/phone/{phone}/{appname} Removes app-specific data for a user identified by phone # Delete user app record by token Source: https://docs.databunker.org/oss/api/user-app/delete-user-app-record-by-token /oss/api/openapi.yml delete /v1/userapp/token/{token}/{appname} Removes app-specific data for a user # Get user app record by email Source: https://docs.databunker.org/oss/api/user-app/get-user-app-record-by-email /oss/api/openapi.yml get /v1/userapp/email/{email}/{appname} Retrieves app-specific data for a user identified by email # Get user app record by login Source: https://docs.databunker.org/oss/api/user-app/get-user-app-record-by-login /oss/api/openapi.yml get /v1/userapp/login/{login}/{appname} Retrieves app-specific data for a user identified by login # Get user app record by phone Source: https://docs.databunker.org/oss/api/user-app/get-user-app-record-by-phone /oss/api/openapi.yml get /v1/userapp/phone/{phone}/{appname} Retrieves app-specific data for a user identified by phone # Get user app record by token Source: https://docs.databunker.org/oss/api/user-app/get-user-app-record-by-token /oss/api/openapi.yml get /v1/userapp/token/{token}/{appname} Retrieves app-specific data for a user # Create a new user record Source: https://docs.databunker.org/oss/api/user/create-a-new-user-record /oss/api/openapi.yml post /v1/user Creates a new encrypted user record. Databunker extracts `login`, `phone`, and `email` from the request and builds hashed indexes for lookup. These values must be unique across all users. # Delete user by email Source: https://docs.databunker.org/oss/api/user/delete-user-by-email /oss/api/openapi.yml delete /v1/user/email/{email} Removes all user records, fulfilling GDPR "right to be forgotten" # Delete user by login Source: https://docs.databunker.org/oss/api/user/delete-user-by-login /oss/api/openapi.yml delete /v1/user/login/{login} Removes all user records, fulfilling GDPR "right to be forgotten" # Delete user by phone Source: https://docs.databunker.org/oss/api/user/delete-user-by-phone /oss/api/openapi.yml delete /v1/user/phone/{phone} Removes all user records, fulfilling GDPR "right to be forgotten" # Delete user by token Source: https://docs.databunker.org/oss/api/user/delete-user-by-token /oss/api/openapi.yml delete /v1/user/token/{token} Removes all user records from the database, keeping only the user token for reference. This fulfills the GDPR "right to be forgotten" requirement. In the enterprise version, deletion can be delayed according to company policy. # Get user by email Source: https://docs.databunker.org/oss/api/user/get-user-by-email /oss/api/openapi.yml get /v1/user/email/{email} Retrieves a user record by email address # Get user by login Source: https://docs.databunker.org/oss/api/user/get-user-by-login /oss/api/openapi.yml get /v1/user/login/{login} Retrieves a user record by login name # Get user by phone Source: https://docs.databunker.org/oss/api/user/get-user-by-phone /oss/api/openapi.yml get /v1/user/phone/{phone} Retrieves a user record by phone number # Get user by token Source: https://docs.databunker.org/oss/api/user/get-user-by-token /oss/api/openapi.yml get /v1/user/token/{token} Retrieves a user record by their unique token # Update user by email Source: https://docs.databunker.org/oss/api/user/update-user-by-email /oss/api/openapi.yml put /v1/user/email/{email} Updates a user record identified by email address # Update user by login Source: https://docs.databunker.org/oss/api/user/update-user-by-login /oss/api/openapi.yml put /v1/user/login/{login} Updates a user record identified by login name # Update user by phone Source: https://docs.databunker.org/oss/api/user/update-user-by-phone /oss/api/openapi.yml put /v1/user/phone/{phone} Updates a user record identified by phone number # Update user by token Source: https://docs.databunker.org/oss/api/user/update-user-by-token /oss/api/openapi.yml put /v1/user/token/{token} Updates a user record. When using JSON, you can remove fields by setting their value to null. All changes are logged in the audit trail. # Architecture Source: https://docs.databunker.org/oss/get-started/architecture Databunker solution **Databunker** is a **vault** for personal records with a twist. **Vault** products are well-known. For example Hashicorp Vault, or cloud-based tools like AWS Secret Manager or GCP Secret Manager. These tools store binary secret values in encrypted form. These secret values can be database passwords, user private keys, or API tokens. The **vault** knows to encrypt the secret value and store it and provide an API for easy access. Databunker has another use-case. It can be used to secretly store the whole user record. This record can include a user name, IP address, password, credit card, blockchain keys, healthcare information, etc... Databunker expects to receive the whole user record in JSON format. Databunker stores encrypted records in the back-end database. Out of the personal record, before encryption, Databunker knows to extract the user's email address, phone number, login value if present, and builds a search index. This search index is also hashed on the database level. So, if the attacker gains access to the Databunker back-end database, everything is encrypted or hashed including the search index. Your code must supply additional user records like first name, last name, user address when calling a Create User API call. These values should be encoded in HTML POST key/value format or JSON format. When a request is made to create a user record, Databunker performs the following operations: 1. Request sanity check and access token check 2. Normalize email address, phone number, login name 3. Optional strict user schema checks if schema is defined in configuration 4. Calculate secure hash values for email address, phone number, login name 5. Duplicate record validation using hashed values of email address, phone number, login name 6. Generate a new record UUID to be used as a user token 7. Encrypt the whole user json and save it in backend database (MySQL, PostgreSQL, SQLite) 8. Return newly generated user token to the caller After creating a new user record, Databunker returns to the caller a user token in UUID format. That token can be saved in existing database instead of storing personal records or PII/PHI. Databunker request flow Databunker provides you an API to lookup user records using the **email address**, **phone number**, **login name** or a **token** received when you create a user record. Databunker was built with privacy in mind and this is where the product really shines. It provides GDPR compliance, i.e. an audit of changes, handling for user requests like forget-me requests, user request change management, optional DPO approval, etc... From a technical perspective, the product has many additional features, like the expiration of records, shareable record identities; additional user records, etc... # Node.js examples Source: https://docs.databunker.org/oss/get-started/examples ## Examples 1. Passwordless Login with Databunker: [GitHub Repository](https://github.com/securitybunker/databunker-nodejs-passwordless-login) 2. Node.js Example with Passport.js, Magic.Link, and Databunker: [GitHub Repository](https://github.com/securitybunker/databunker-nodejs-example) 3. Secure Session Storage for Node.js Apps: [Detailed Guide](https://databunker.org/use-case/secure-session-storage/#databunker-support-for-nodejs) ## Node.JS modules 1. `@databunker/store` from [https://github.com/securitybunker/databunker-store](https://github.com/securitybunker/databunker-store) 2. `@databunker/session-store` from [https://github.com/securitybunker/databunker-session-store](https://github.com/securitybunker/databunker-session-store) # Databunker Source: https://docs.databunker.org/oss/get-started/overview Databunker is an open-source, Go-based tool for secure personal data tokenization and storage. It can be deployed using Docker Compose or a Kubernetes Helm chart and is designed to help developers protect sensitive data such as PII, PHI, and KYC with minimal effort. ### πŸ’£ The Big Problem with Traditional Database Encryption Traditional database encryption solutions often provide a false sense of security. While they may encrypt data at rest, they leave critical vulnerabilities: * **Encryption alone isn’t enough:** Most vendors offer disk-block encryption, ignoring API-level encryption * **Vulnerable GraphQL Queries:** Unfiltered queries can expose unencrypted data to attackers * **SQL Injection Risks:** Attackers can retrieve plaintext data through SQL injections Databunker addresses these gaps with a secure, developer-focused solution for personal data tokenization and storage. ### πŸ› οΈ Databunker Features * **Tokenization Engine**: Generates UUID tokens for safe data referencing in applications * **Encrypted Storage**: Secures sensitive records with advanced encryption layer * **Injection Protection**: Blocks SQL and GraphQL injection attacks by design * **Secure Indexing**: Uses hash-based indexing for search queries * **No Plaintext Storage**: Ensures all data is encrypted at rest * **Restricted Bulk Retrieval**: Disabled by default to prevent data leaks * **API-Based Access**: Integrates with your backend via a NoSQL-like API * **Fast Integration**: Set up secure data protection in under 10 minutes For **credit-card tokenization** or **enterprise security features** check out [Databunker Pro](/pro/get-started/overview). ### ⚑ Why Databunker? Databunker provides a robust, open-source vault that eliminates the false sense of security from traditional encryption methods, offering developers a practical way to protect sensitive data. ### πŸš€ Deployment & Usage * **Self-Hosted**: Run on your cloud or on-premises infrastructure * **Open-Source**: Licensed under MIT for free commercial use * **GDPR Compliant**: Meets modern privacy regulation requirements * **High Performance**: Go-powered API ensures fast tokenization and data access ### πŸ” How It Works 1. Store sensitive data in Databunker via API calls 2. Receive UUID tokens to reference data securely in your application 3. Query data using secure, hash-based indexing 4. Benefit from built-in protections against injections and bulk data leaks Get started with Databunker to secure your sensitive data efficiently. Pseudonymized identity # Quickstart Source: https://docs.databunker.org/oss/get-started/quickstart ## Step 1: Starting the Databunker container The easiest way to start using Databunker is by running it as a Docker container. Once the container is running, Databunker opens port 3000 and listens for incoming requests. To launch Databunker with a `DEMO` root access key, ideal for local testing and development, use the following command: ```bash theme={null} docker run -p 3000:3000 -d --rm --name databunker securitybunker/databunker demo ``` For detailed installation instructions, please refer to the [full installation guide](/oss/installation/overview). ## Step 2: Creating a User Record Databunker's most popular API request is to store user records. For each new user record, Databunker generates and returns a **user token** in UUID format. GDPR Relevance: * Under **GDPR**, this **user token** is referred to as a **pseudonymized identity**. This token can be safely stored in your regular database or logs, as long as **no** additional personal information is stored with it. * **Pseudonymization** reduces the risk of directly associating personal data with an individual, reinforcing data protection and privacy principles. * For instance, when you receive a **Right to be forgotten (RTBF) request**, you can remove the personal data from Databunker without affecting other systems. Use this command to create the user record: ```bash theme={null} curl -s http://localhost:3000/v1/user \ -X POST -H "X-Bunker-Token: DEMO" \ -H "Content-Type: application/json" \ -d '{"first":"John","last":"Doe","login":"john","phone":"4444","email":"user@gmail.com"}' ``` Output: ```json theme={null} { "status": "ok", "token": "eeb04dd7-ecb2-c957-2875-5b98897b21a6" } ``` ## Step 3: Retrieving user record You can retrieve user records using indexed fields, such as **email address**, **login name**, **user token**, or **custom index**. To fetch customer records by user token, use this command: ```bash theme={null} curl -s -H "X-Bunker-Token: DEMO" -X GET http://localhost:3000/v1/user/token/eeb04dd7-ecb2-c957-2875-5b98897b21a6 ``` You can integrate Databunker into your application's sign-in logic and search for customer records using an email address or login name: ```bash theme={null} curl -s -H "X-Bunker-Token: DEMO" -X GET http://localhost:3000/v1/user/email/user@gmail.com curl -s -H "X-Bunker-Token: DEMO" -X GET http://localhost:3000/v1/user/login/john ``` ## Full lists of API requests: For a full list of available requests, please check the [API Reference](/oss/api/overview). ## Step 4: Accessing the Web UI Databunker includes a built-in web UI. For quick access, we’ve pre-installed Databunker, which you can access at: demo.databunker.org. Use the `DEMO` root token to access the admin panel. If you deploy Databunker using Docker, this interface is available by default at: localhost:3000. In the demo version, the root token is set to `DEMO` by default. The **admin** or **Data Protection Officer (DPO)** can use the web interface to: 1. Delete user records to comply with GDPR RTBF "forget me" requests 2. Generate personal data reports and review audit logs 3. Manage personal data processing activities #### End-User Access: Databunker's optional customer portal lets users securely access, manage, and update their personal data, supporting GDPR compliance. Key features include secure login, data review, and audit log access. If you created a sample user with the phone number `4444`, as shown in the **Creating a User Record** section, you can use `4444` as both the phone number and password to access the customer portal. ## Step 5: View Node.js code examples 1. Passwordless Login with Databunker: [GitHub Repository](https://github.com/securitybunker/databunker-nodejs-passwordless-login) 2. Node.js Example with Passport.js, Magic.Link, and Databunker: [GitHub Repository](https://github.com/securitybunker/databunker-nodejs-example) 3. Secure Session Storage for Node.js Apps: [Detailed Guide](https://databunker.org/use-case/secure-session-storage/#databunker-support-for-nodejs) #### Node.js modules 1. `@databunker/store` from [https://github.com/securitybunker/databunker-store](https://github.com/securitybunker/databunker-store) 2. `@databunker/session-store` from [https://github.com/securitybunker/databunker-session-store](https://github.com/securitybunker/databunker-session-store) # Detailed installation guide Source: https://docs.databunker.org/oss/installation/overview ## Method 1: Quick installation * The easiest way to start using Databunker is to deploy it as a standard Docker container with minimal parameters. * In this setup, it uses an internal **SQLite database** to store encrypted records. * You can use `DEMO` as a root token when making [API requests](/oss/api/overview) **Disadvantages:** * Utilizes a local SQLite database for storing encrypted records * Lack of security; using `DEMO` as a root access token * Not recommended for production use **Run the following commands to start Databunker:** ```bash theme={null} DATABUNKER_MASTERKEY=`< /dev/urandom LC_CTYPE=C tr -dc 'a-f0-9' | head -c${1:-48};` echo "DATABUNKER_MASTERKEY value is $DATABUNKER_MASTERKEY" docker run -p 3000:3000 -d -e DATABUNKER_MASTERKEY=$DATABUNKER_MASTERKEY --name databunker securitybunker/databunker demo ``` The first command generates the encryption key for Databunker's internal database. Be sure to save it for future use. Open your browser and navigate to [http://localhost:3000/](http://localhost:3000/) to access the product's user interface. `Note:` * If the **databunker** container stops, you can restart the service by running `docker start databunker`. * For production environments, we recommend using a MySQL or PostgreSQL backend instead. ## Method 2: Start Databunker and backend db with docker compose We prepared a number of scripts and configuration files you can use with Docker Compose. All these files are available in the project's github repository. Before starting Docker Compose, you need to generate several secret variables used by the containers. These variables include: * Passwords for MySQL or PostgreSQL databases * A self-signed SSL certificate * Databunker root token, and more For instance, the **DATABUNKER\_ROOTTOKEN** variable will be stored in the `.env/databunker-root.env` file. This value is used as the root token when making Databunker API requests. The required secret files will be saved in the `.env` directory. Use one of the following scripts from the project's GitHub repository to generate configuration secrets: * ./generate-mysql-env-files.sh * ./generate-mysql-demo-env-files.sh * ./generate-pgsql-env-files.sh * ./generate-pgsql-demo-env-files.sh After generating the secrets, you can start Databunker with MySQL using: ```bash theme={null} docker-compose -f docker-compose-mysql.yml up -d ``` Or, start Databunker with PostgreSQL using: ```bash theme={null} docker-compose -f docker-compose-pgsql.yml up -d ``` Once started, you can access Databunker by opening your browser and navigating to [http://localhost:3000/](http://localhost:3000/). ## Method 3: Automatic deployment in AWS cloud We have built Terraform configuration files and Helm charts to deploy Databunker with all required components in AWS. Detailed instructions can be found here: * [https://github.com/securitybunker/databunker/tree/master/terraform/aws](https://github.com/securitybunker/databunker/tree/master/terraform/aws) * [https://github.com/securitybunker/databunker/tree/master/charts/databunker](https://github.com/securitybunker/databunker/tree/master/charts/databunker) ## Method 4: Step-by-step production installation **Start with backend database** For production installation, you can use **MySQL** or **PostgreSQL** backend databases. This databse will be used to store encrypted user records. For example, you can spin MySQL or PostgreSQL as a container or use a cloud RDS version provided by Google Cloud and AWS, etc... For example, use the following command to start MySQL server. It will create a `databunkerdb` database for Databunker and create `bunkeruser` for Databunker access to MySQL. ```bash theme={null} mkdir ~/data chmod 0777 ~/data docker run --restart unless-stopped \ -v ~/data:/var/lib/mysql \ -e MYSQL_ROOT_PASSWORD=SuperAdmin4 \ -e MYSQL_DATABASE=databunkerdb \ -e MYSQL_USER=bunkeruser \ -e MYSQL_PASSWORD=BunkerUserPassword4 \ --name=mysqlsrv -d mysql/mysql-server ``` `Note:` make sure to change the passwords above. **First Databunker initialization step** Before Databunker can serve user requests it needs to create all tables; generate a master encryption key if not provided; generate root access token if not provided. This process is called **Databunker initialization**. You will need to do it just for the first time. Run the following command to initialize Databunker: ```bash theme={null} docker run --rm -it --link mysqlsrv \ -e MYSQL_HOST=mysqlsrv \ -e MYSQL_PORT=3306 \ -e MYSQL_USER_NAME=bunkeruser \ -e MYSQL_USER_PASS=BunkerUserPassword4 \ --entrypoint /bin/sh \ --name dbunker securitybunker/databunker \ -c '/databunker/bin/databunker -init -db databunkerdb -conf /databunker/conf/databunker.yaml' ``` In the command output, you will see the `Master key` and `API Root token` values. **Start the Databunker service** After extracting `DATABUNKER_MASTERKEY` you can start the Databunker service using the following command: ```bash theme={null} docker run --restart unless-stopped -d -p 3000:3000 \ --link mysqlsrv -e MYSQL_HOST=mysqlsrv \ -e DATABUNKER_MASTERKEY=8c9e892a1732881e14960f2b0437a720ad01ae47cd23baa7 \ -e MYSQL_PORT=3306 \ -e MYSQL_USER_NAME=bunkeruser \ -e MYSQL_USER_PASS=BunkerUserPassword4 \ --entrypoint /bin/sh \ --name dbunker securitybunker/databunker \ -c '/databunker/bin/databunker -start -db databunkerdb -conf /databunker/conf/databunker.yaml' ``` ## Advanced configuration Databunker uses the `databunker.yaml` configuration file. You can modify this file to set custom email gateway, SMS gateway, service logo, and more. There are several ways to load a new configuration file in Databunker: * Build a new Docker container based on Databunker's Dockerfile and include your custom configuration file inside it * Create a new configuration file and mount it to the Databunker container Follow these steps to mount an external configuration file: **Step 1. Download the default configuration file** Create a `./conf` directory and download the default configuration file in it: ```bash theme={null} mkdir ~/conf curl https://raw.githubusercontent.com/securitybunker/databunker/master/databunker.yaml \ -o ~/conf/databunker.yaml ``` **Step 2: Modify the Configuration File** Edit the configuration file with your changes: **\~/conf/databunker.yaml** **Step 3: Start the Databunker Container** Use the following command to start the Databunker container with the custom configuration: ```bash theme={null} docker run --restart unless-stopped -d -p 3000:3000 -v ~/conf:/databunker/conf \ --link mysqlsrv -e MYSQL_HOST=mysqlsrv \ -e DATABUNKER_MASTERKEY=8c9e892a1732881e14960f2b0437a720ad01ae47cd23baa7 \ -e MYSQL_PORT=3306 \ -e MYSQL_USER_NAME=bunkeruser \ -e MYSQL_USER_PASS=BunkerUserPassword4 \ --entrypoint /bin/sh \ --name dbunker securitybunker/databunker \ -c '/databunker/bin/databunker -start -db databunkerdb -conf /databunker/conf/databunker.yaml' ``` This command starts Databunker with the custom configuration file located in the \~/conf directory. ## SSL certificates You can generate SSL certificates and place them in the `/databunker/certs` directory in the running container. Use the following command to generate self-signed certificate: ```bash theme={null} cd ~ mkdir -p certs cd certs openssl req -new -newkey rsa:4096 -days 365 -nodes -x509 \ -subj "/e=UK/ST=/L=London/O=Your-company Ltd./CN=databunker.your-company.com" \ -keyout server.key -out server.cer ``` Next, map `/databunker/certs` directory inside container to the **\~/certs/** directory as: ```bash theme={null} cd ~ docker run --restart unless-stopped -d -p 3000:3000 -v ~/conf:/databunker/conf -v ~/certs:/databunker/certs \ --link mysqlsrv -e MYSQL_HOST=mysqlsrv \ -e DATABUNKER_MASTERKEY=8c9e892a1732881e14960f2b0437a720ad01ae47cd23baa7 \ -e MYSQL_PORT=3306 \ -e MYSQL_USER_NAME=bunkeruser \ -e MYSQL_USER_PASS=BunkerUserPassword4 \ --entrypoint /bin/sh \ --name dbunker securitybunker/databunker \ -c '/databunker/bin/databunker -start -db databunkerdb -conf /databunker/conf/databunker.yaml' ``` **Use certificates generated by Letsencrypt** Copy Letsencrypt generated file **privkey.pem** to \~/certs/server.key Copy Letsencrypt generated file **fullchain.pem** file to \~/certs/server.cer ## Create a test record You can download and run a small test script that will create a user record, user app record, user consent, etc... ```bash theme={null} curl https://raw.githubusercontent.com/securitybunker/databunker/master/create-test-user.sh -o test.sh chmod 755 ./test.sh ./test.sh ``` ### Built-in web UI You can now open browser at [http://localhost:3000/](http://localhost:3000/) Use the following account details: Email: [test@securitybunker.io](mailto:test@securitybunker.io) Phone: 4444 Code: 4444 ## Next steps * [Quickstart](/oss/get-started/quickstart) β€” create and retrieve your first user record * [Online demo](https://demo.databunker.org/) β€” pre-installed Databunker, use the `DEMO` root token * [Code examples](/oss/get-started/examples) * [Architecture](/oss/get-started/architecture) * [Source code](https://github.com/securitybunker/databunker/) # Conditional Role-Based Access Control (CRBAC) Source: https://docs.databunker.org/pro/administration/access-control **Conditional Role-Based Access Control (CRBAC)** is an advanced access control system that extends traditional Role-Based Access Control (RBAC) by introducing dynamic conditions that determine access rights. For the credential types that policies govern (root, tenant, role, and user tokens), see the [Authentication reference](/pro/api/authentication). CRBAC is particularly useful for businesses that need to comply with various privacy laws, such as: 1. **DPDPA** (India's Digital Personal Data Protection Act) 2. **FERPA** (Family Educational Rights and Privacy Act in the USA), which governs student education records 3. **GDPR** (General Data Protection Regulation in the EU) With Databunker Pro, customers can easily implement solutions that align with these regulations, ensuring secure and compliant PII management. ## Key Features of CRBAC * **Hierarchical Access Control:** Supports parent-child relationships in data access, enabling fine-grained permissions. * **Context-Aware Policies:** Defines access based on specific attributes like user roles, organizational structures, and compliance requirements. * **Dynamic Consent Enforcement:** Incorporates consent management for accessing PII. * **Group-Based Roles:** Databunker supports groups of users, where each member within a group can have distinct roles. For instance, in an educational group, roles like **Teacher** and **Student** can be assigned, or in a family group, roles such as **Parent** and **Child**. * **Similar to AWS IAM Policies:** Uses a declarative approach to grant or deny access based on conditions. ## Policy Structure CRBAC policies resemble AWS IAM policies, defining **who** (principale) can perform **what** (actions) on **which** (resources) under **which conditions**. ### Example Policy: Parent-Child Relationship Enforcement In Databunker Pro, you can create a custom group for family members. Within this group, parents will have read and write access to their child's information. You can use the following policy to grant parents access to their child's PII and consent information. ```json theme={null} { "Effect": "Allow", "Principal": { "Role": "parent" }, "Action": [ "UserGet", "UserUpdate", "BulkListGroupUsers", "AgreementGet", "AgreementAccept", "AgreementCancel", "AgreementListUserAgreements" ], "Resource": [ "${target_group_members:role/child}.profile", "${target_group_members:role/child}.agreement" ], "Condition": { "StringEquals": { "${user_group_id}": "${target_group_id}" } } } ``` ### Example Policy: Teacher-Parent Access This policy will grant to a teacher entity access to the student's parent information. ```json theme={null} { "Effect": "Allow", "Principal": { "Role": "teacher" }, "Action": ["UserGet", "BulkListGroupUsers"], "Resource": [ "${target_group_members:role/parent}.profile.name", "${target_group_members:role/parent}.profile.phone" ], "Condition": { "ForAnyValue:ListIntersect": { "${user_group_members:role/student}": "${target_group_members:role/child}" } } } ``` ## Passing runtime context with `request_metadata` Most Databunker Pro API endpoints accept an optional **`request_metadata`** object on the request body. The caller (application code, an API gateway, or a tokenisation proxy) uses it to pass runtime context β€” values like the calling environment, the purpose of the request, the originating IP address, a ticket number β€” that the access-control engine can evaluate at policy time. CRBAC `Condition` blocks can reference `request_metadata` values directly, so the same policy can grant or deny access based on **why** and **where** the request is coming from, not just **who** is making it. This is purpose-of-use enforcement. ### Example: caller-supplied context ```bash theme={null} curl -X POST https://your-databunker-instance/v2/UserGet \ -H "X-Bunker-Token: YOUR_ACCESS_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "mode": "email", "identity": "jane@example.com", "request_metadata": { "environment": "production", "purpose": "fraud-investigation", "caller_ip": "10.0.12.34", "ticket_id": "INC-44218" } }' ``` ### Example: policy that evaluates `request_metadata` This policy allows a `security-analyst` role to read full user records **only** when the request is tagged with `purpose: fraud-investigation` and originates from the production environment: ```json theme={null} { "Effect": "Allow", "Principal": { "Role": "security-analyst" }, "Action": ["UserGet"], "Resource": ["*.profile"], "Condition": { "StringEquals": { "${request_metadata.purpose}": "fraud-investigation", "${request_metadata.environment}": "production" } } } ``` A request from the same role without those metadata values β€” or with different ones β€” is denied. ### What to put in `request_metadata` `request_metadata` is free-form, so the keys are conventions you adopt for your deployment. Typical keys we see in production: | Key | Purpose | | ------------- | -------------------------------------------------------------------- | | `environment` | `production` / `staging` / `dev` β€” scopes policies per environment. | | `purpose` | A business-domain purpose-of-use code (e.g., `fraud-investigation`). | | `caller_ip` | Client IP β€” useful for IP-range conditions. | | `ticket_id` | Linking the access to a ticket / case for accountability. | | `app_name` | Calling application β€” useful when multiple apps share a role. | Every value passed in `request_metadata` is recorded in the audit event for the request, so it doubles as accountability metadata even when no policy references it. ## Field-Level Masking in Responses When a policy grants access to a subset of a user's profile fields, Databunker Pro applies the policy at response time. The original record stays untouched in the vault; the API response is filtered for the calling principal. The masking strategy is **asymmetric by type** so that strongly-typed clients (TypeScript, Python type-hints, Java, generated SDKs) do not encounter silent type mismatches: * **String fields** that the caller is not authorized to read are replaced with the literal `"***"`. The field stays in the response so the client can detect that the field exists. * **All other types** (`number`, `boolean`, array, nested object) are **omitted from the response entirely** when masked. This avoids type-corruption bugs like `profile.age + 1` evaluating to `"***1"` because the engine had substituted a string for a number. ### Example Suppose a `sales` user has a policy allowing only `${target_group_members:role/lead}.profile.email`. A lead's stored profile is: ```json theme={null} { "login": "lead42", "name": "Jane Doe", "email": "jane@example.com", "phone": "+15551234567", "age": 34, "verified": true, "tags": ["enterprise", "warm"], "address": { "city": "Springfield", "zip": "99999" } } ``` Calling `UserGet` with the sales user's token returns: ```json theme={null} { "status": "ok", "profile": { "email": "jane@example.com", "login": "***", "name": "***", "phone": "***" } } ``` Notice: * `email` is visible because the policy granted it. * `login`, `name`, `phone` are strings β€” present in the response with value `"***"`. * `age` (number), `verified` (boolean), `tags` (array), `address` (object) are absent from the `profile` object entirely. ### TypeScript example ```typescript theme={null} interface UserResponse { status: string; profile: { email?: string; login?: string; name?: string; phone?: string; age?: number; verified?: boolean; tags?: string[]; address?: { city: string; zip: string }; }; } const r: UserResponse = await api.userGet({mode: "login", identity: "lead42"}); // Safe: optional fields handled with the `?` operator. if (r.profile.age !== undefined) { console.log("Age:", r.profile.age + 1); // never executes when age is masked } ``` ## Why Choose CRBAC? 1. **Compliance-Ready:** CRBAC ensures organizations meet legal and regulatory requirements, including FERPA and DPDPA. 2. **Dynamic Access Control:** Unlike static RBAC, CRBAC adapts access rights based on real-time conditions. 3. **Fine-Grained Permissions:** Allows precise control over PII data access, reducing the risk of unauthorized exposure. ## Implementing CRBAC with Databunker Pro Databunker Pro simplifies CRBAC implementation by providing: 1. Built-in support for conditional access policies 2. Secure PII storage with compliance enforcement 3. A developer-friendly API for managing role-based conditions By leveraging **Databunker Pro**, organizations can seamlessly enforce FERPA-compliant data access policies while maintaining flexibility for other regulatory frameworks. ## Conclusion Conditional Role-Based Access Control (CRBAC) is essential for organizations handling sensitive PII under strict compliance regulations. With Databunker Pro, businesses can implement secure, scalable, and regulation-compliant access control mechanisms tailored to their needs. # Encryption key rotation Source: https://docs.databunker.org/pro/administration/key-rotation Encryption key rotation is a critical process in Databunker Pro to maintain the confidentiality and integrity of sensitive data. The **Wrapping Key**, which encrypts the **Master Key**, is rotated periodically as part of this process to enhance security. ## What is the Master Key? The **Master Key** is the core encryption key used to protect sensitive data. It is never exposed and is encrypted using a Wrapping Key for additional security. ## What is the Wrapping Key? The Wrapping Key is a cryptographic key used to encrypt the **Master Key** in Databunker Pro. It acts as an additional layer of protection for the Master Key ## Importance of Key Rotation: 1. **Limiting Key Exposure:** Regular rotation reduces the window of opportunity for potential attackers to compromise the key. 2. **Compliance:** Many security standards and regulations require periodic key rotation. 3. **Mitigating Long-term Attacks:** Rotation helps protect against slow, persistent attempts to break encryption. ## Best Practices: * Rotate the Wrapping Key at regular intervals (e.g., every 90 days or annually). * Implement automated reminders for key rotation. * Maintain a secure log of key rotations for audit purposes. * Test the rotation process regularly to ensure smooth execution when needed. ## Recovery: In case the current Wrapping Key is lost or compromised, Databunker Pro allows for recovery using [Shamir Key Shares](/pro/administration/shamir-keys). This ensures that the Master Key can be safely re-encrypted with a new Wrapping Key without exposure. # Master key Source: https://docs.databunker.org/pro/administration/master-key The Master Key is a critical component of Databunker Pro's security architecture. It serves as the primary encryption key for protecting sensitive data stored within the system. ## Key Points: * The Master Key is automatically generated during the initial setup of Databunker Pro. * Unlike the open-source version, the Master Key is never exposed in the Pro Version. * The Master Key is encrypted using a Wrapping Key, adding an extra layer of security. ## Enhanced Security in Pro Version: In Databunker Pro, the Master Key's security is significantly strengthened compared to the open-source version: 1. **No Exposure:** The Master Key is never revealed or accessible to users or administrators, reducing the risk of key compromise. 2. **Wrapping Key Protection:** The Master Key is encrypted using a Wrapping Key. This means that even if an attacker gains access to the encrypted Master Key, they cannot use it without the Wrapping Key. 3. **Separation of Concerns:** By using a Wrapping Key to encrypt the Master Key, Databunker Pro implements a separation of concerns. This allows for more flexible key management and enhances overall security. 4. **Key Rotation Support:** The use of a Wrapping Key facilitates easier and more secure key rotation processes, allowing for regular updates to the encryption without exposing the Master Key. 5. **Recovery Mechanism:** In case of Wrapping Key loss, the Shamir Key Shares provide a secure way to recover and re-encrypt the Master Key without ever exposing it. By implementing these additional security measures, Databunker Pro ensures that the Master Key remains secure throughout its lifecycle, significantly reducing the risk of unauthorized access to sensitive data. # Multi-tenancy Source: https://docs.databunker.org/pro/administration/multi-tenancy Databunker Pro supports multi-tenancy, allowing you to manage multiple tenants within a single instance. This document outlines the API endpoints for creating, managing, and interacting with tenants. **Note:** Multi-tenancy requires PostgreSQL as the backend database and is not supported with MySQL. **Multi-tenancy is per-instance.** All tenants live inside the same Databunker Pro deployment and share the same physical region. If you need to keep PII inside different *legal jurisdictions* β€” for example because of GDPR cross-border rules, India's DPDPA, Russia's 152-FZ, or similar β€” multi-tenancy is not the right tool. Instead, run one Databunker Pro instance per jurisdiction and unify operations via Databunker DPO. See [Multi-jurisdiction deployment](/pro/concepts/global-deployment). ## Create Tenant Creates a new tenant in the Databunker Pro system. ```bash theme={null} curl -H 'X-Bunker-Token: ROOT-ACCESS-TOKEN' -X POST /v2/TenantCreate \ --data '{"tenantorg":"testorg","tenantname":"testname"}' ``` ### Request Body | Field | Type | Description | | ---------- | ------ | --------------------------------------------------------- | | tenantname | string | The name of the tenant. Must match the format: \[a-z0-9]+ | | tenantorg | string | The organization slug associated with the tenant | ### Response | Field | Type | Description | | ------ | ------ | ------------------------------------- | | status | string | Operation status ("ok" if successful) | | xtoken | string | Tenant access token in UUID format | ### Example Response ```json theme={null} { "status": "ok", "xtoken": "TENANT-ACCESS-TOKEN" } ``` ### Notes * The `TENANT-ACCESS-TOKEN` is a special token to authenticate all tenant related commands. For example create user records. ## Create a Tenant User Account You have two methods to specify the tenant name: you can either use the `X-Bunker-Tenant` HTTP header or include the tenant name in the hostname. If the `X-Bunker-Tenant` header is missing, Databunker Pro will attempt to retrieve the tenant name from the subdomain in the hostname. If neither option is available, a **default** tenant is used. Example commands: ```bash theme={null} curl -H 'X-Bunker-Token: XXXXXXX' \ -H 'X-Bunker-Tenant: TENANT-NAME' \ -H 'Content-Type: application/json' \ -X POST 'http://localhost:3000/v2/UserCreate' \ --data '{"profile":{"firstname":"John","lastname":"Doe","email":"user@email.com","login":"john"}}' ``` ```bash theme={null} curl -H 'X-Bunker-Token: XXXXXXX' \ -X POST https://TENANT-NAME.databunker-domain.com/v2/UserCreate \ --data '{"profile":{"firstname":"John","lastname":"Doe","email":"user@email.com","login":"john"}}' ``` ### Notes * Replace `TENANT-NAME` in the URL with the actual name of the tenant. * The request body and response format are identical to the standard `UserCreate` call β€” see the [API Reference](/pro/api/overview). The only difference is the tenant context supplied via the `X-Bunker-Tenant` header or the subdomain. ## Rename Tenant Renames an existing tenant. ```bash theme={null} curl -H 'X-Bunker-Token: TENANT-ACCESS-TOKEN' \ -X POST https://old-tenant.databunker-domain.com/v2/TenantUpdate \ --data '{"tenantname":"new-name"}' ``` ### Request Body | Field | Type | Description | | ---------- | ------ | -------------------------------------------------------------- | | tenantname | string | The new name for the tenant. Must match the format: \[a-z0-9]+ | ### Example Request ```json theme={null} { "tenantname": "new-name" } ``` ### Response | Field | Type | Description | | ------ | ------ | ------------------------------------- | | status | string | Operation status ("ok" if successful) | ### Example Response ```json theme={null} { "status": "ok" } ``` ### Other commands: For a full list of API requests, check out the [API Reference](/pro/api/overview). ## General Notes 1. **Tenant Name Format**: Tenant names must follow the format `[a-z0-9]+`. This means they can only contain lowercase letters and numbers. 2. **Tenant-Specific URLs**: After creating a tenant, you'll interact with tenant-specific endpoints using URLs in the format `https://tenant-name.databunker-domain.com/...`. 3. **Authentication**: Most endpoints will require the `TENANT-ACCESS-TOKEN` for authentication. Include this token in the `X-Bunker-Token` header or as specified in the Databunker Pro documentation. 4. **SSL/TLS**: Always use HTTPS for secure communication with the API endpoints. For more detailed information on request/response formats, additional endpoints, or error handling, please refer to the complete Databunker Pro API documentation. ## Cross-tenant System Operations Databunker Pro provides a dedicated **System Operations** API for cross-tenant queries. These endpoints are used for compliance workflows that span the entire deployment β€” DSAR fulfillment, regulator queries, right-to-erasure, and forensic investigations β€” where the answer to *"find every record about this person across all our tenants"* must come from one call rather than N tenant-by-tenant queries. ### Access control All System Operations endpoints are: * **Restricted to the main tenant admin (`tenantID = 1`)** β€” the highest-privilege principal of the deployment. Tenant-level admins cannot invoke these endpoints. * **Gated by a `bulkListUnlock` UUID** β€” short-lived, must be obtained via `/v2/BulkListUnlock` immediately before the call. This is the same default-deny mechanism used for bulk operations: an admin token alone is not enough. * **Audited on every call.** ### Endpoints | Endpoint | Purpose | | ----------------------------------- | ------------------------------------------------------------------------------------------------------------------ | | `POST /v2/SystemGetUserProfiles` | Retrieve all profiles for a user (identified by `email` / `phone` / `login` / `custom`) across every tenant. | | `POST /v2/SystemSearchUserProfiles` | Fuzzy-search for user profiles across every tenant. Mode is auto-detected from the identity value. | | `POST /v2/SystemDeleteUserProfiles` | Delete all profiles for a user across every tenant β€” or restrict to a single tenant via `tenantid` / `tenantname`. | | `POST /v2/SystemRestoreUserProfile` | Restore a previously-deleted user profile for a specific tenant from version history. | Every response includes the originating `tenantid` and `tenantname` for each profile, so the caller can see exactly which tenants the person appeared in. ### Example: find a user across every tenant ```bash theme={null} # Step 1: obtain a short-lived unlock UUID UNLOCK=$(curl -s -X POST https://your-databunker-instance/v2/BulkListUnlock \ -H "X-Bunker-Token: MAIN_ADMIN_TOKEN" | jq -r .unlockuuid) # Step 2: cross-tenant lookup curl -X POST https://your-databunker-instance/v2/SystemGetUserProfiles \ -H "X-Bunker-Token: MAIN_ADMIN_TOKEN" \ -H "Content-Type: application/json" \ -d "{ \"mode\": \"email\", \"identity\": \"john.doe@example.com\", \"unlockuuid\": \"$UNLOCK\" }" ``` ### Example response ```json theme={null} { "status": "ok", "total": 3, "rows": [ { "tenantid": 7, "tenantname": "student-services", "token": "abc-...", "profile": { "...": "..." } }, { "tenantid": 9, "tenantname": "analytics", "token": "def-...", "profile": { "...": "..." } }, { "tenantid": 12,"tenantname": "alumni", "token": "ghi-...", "profile": { "...": "..." } } ] } ``` The same person appears under three different tokens β€” one per tenant β€” which is the expected outcome of the per-tenant uniqueness model. The System Operations response is the only place these tokens are correlated, and the correlation is audited. # Shamir keys Source: https://docs.databunker.org/pro/administration/shamir-keys Shamir Keys, based on Shamir's Secret Sharing scheme, provide a robust and secure method for backing up and recovering critical encryption keys in Databunker Pro. ## What are Shamir Keys? Shamir Keys are a set of cryptographic key shares created using Shamir's Secret Sharing algorithm. This method allows a secret (in this case, the Wrapping Key) to be divided into multiple parts. ## Key Features: 1. **Threshold Scheme:** Databunker Pro uses a 3-out-of-5 scheme, meaning any 3 out of the 5 generated key shares can reconstruct the original secret. 2. **Security:** No single key share contains enough information to reconstruct the secret on its own. 3. **Flexibility:** Allows for distributed key storage among trusted parties or locations. ## Use in Databunker Pro: * During setup, Databunker Pro generates 5 Shamir Key Shares. * These shares can be used to recover the Wrapping Key if it's lost or compromised. * The recovered Wrapping Key can then be used to safely re-encrypt the Master Key. ## Best Practices for Managing Shamir Keys: 1. **Secure Storage:** Store each key share in a different secure location. 2. **Access Control:** Limit access to key shares to authorized personnel only. 3. **Regular Audits:** Periodically verify the integrity and availability of all key shares. 4. **Documentation:** Maintain clear, secure documentation on the location and access procedures for each key share. 5. **Disaster Recovery Planning:** Include Shamir Key recovery procedures in your disaster recovery plans. ## Recovery Process: 1. Gather any 3 of the 5 Shamir Key Shares. 2. Use Databunker Pro's built-in recovery tool to reconstruct the Wrapping Key. 3. Generate a new Wrapping Key and use it to start the Databunker Pro process. By implementing Shamir Keys, Databunker Pro provides a secure and resilient method for key backup and recovery, ensuring that critical encryption keys can be restored even in worst-case scenarios, without compromising the overall security of the system. # Accept agreement Source: https://docs.databunker.org/pro/api/agreement-management/accept-agreement /pro/api/openapi.yml post /v2/AgreementAccept Records user's acceptance of a legal basis/agreement # Cancel agreement Source: https://docs.databunker.org/pro/api/agreement-management/cancel-agreement /pro/api/openapi.yml post /v2/AgreementCancel Cancels a user's agreement # Get user agreement Source: https://docs.databunker.org/pro/api/agreement-management/get-user-agreement /pro/api/openapi.yml post /v2/AgreementGet Retrieves a specific agreement for a user # List user agreements Source: https://docs.databunker.org/pro/api/agreement-management/list-user-agreements /pro/api/openapi.yml post /v2/AgreementListUserAgreements Lists all agreements for a specific user # Request agreement cancellation Source: https://docs.databunker.org/pro/api/agreement-management/request-agreement-cancellation /pro/api/openapi.yml post /v2/AgreementCancelRequest Creates a cancellation request for an agreement (requires approval) # Revoke all agreements Source: https://docs.databunker.org/pro/api/agreement-management/revoke-all-agreements /pro/api/openapi.yml post /v2/AgreementRevokeAll Revokes all agreements for a specific legal basis # Create application data for user Source: https://docs.databunker.org/pro/api/app-data-management/create-application-data-for-user /pro/api/openapi.yml post /v2/AppdataCreate Stores application-specific data for a user # Delete application data for user Source: https://docs.databunker.org/pro/api/app-data-management/delete-application-data-for-user /pro/api/openapi.yml post /v2/AppdataDelete Deletes application-specific data for a user # Get application data for user Source: https://docs.databunker.org/pro/api/app-data-management/get-application-data-for-user /pro/api/openapi.yml post /v2/AppdataGet Retrieves application-specific data for a user # List all application names Source: https://docs.databunker.org/pro/api/app-data-management/list-all-application-names /pro/api/openapi.yml post /v2/AppdataListAppNames Retrieves a list of all application names in the system # List app data versions Source: https://docs.databunker.org/pro/api/app-data-management/list-app-data-versions /pro/api/openapi.yml post /v2/AppdataListVersions Lists all versions of application data for a user # List user application names Source: https://docs.databunker.org/pro/api/app-data-management/list-user-application-names /pro/api/openapi.yml post /v2/AppdataListUserAppNames Retrieves a list of application names for a specific user # Request app data update Source: https://docs.databunker.org/pro/api/app-data-management/request-app-data-update /pro/api/openapi.yml post /v2/AppdataUpdateRequest Creates an update request for app data (requires approval) # Update application data for user Source: https://docs.databunker.org/pro/api/app-data-management/update-application-data-for-user /pro/api/openapi.yml post /v2/AppdataUpdate Updates application-specific data for a user # Get specific audit event Source: https://docs.databunker.org/pro/api/audit-management/get-specific-audit-event /pro/api/openapi.yml post /v2/AuditGetEvent Retrieves detailed information about a specific audit event # List user audit events Source: https://docs.databunker.org/pro/api/audit-management/list-user-audit-events /pro/api/openapi.yml post /v2/AuditListUserEvents Retrieves audit events for a specific user # Authentication Source: https://docs.databunker.org/pro/api/authentication Every credential type in Databunker Pro β€” root tokens, tenant tokens, role and user xtokens, and the bulk-unlock UUID β€” and how to obtain and use each one. Every authenticated API call carries a credential in the `X-Bunker-Token` header. Databunker Pro has a small hierarchy of credential types, each scoped to a different level of access. This page is the single reference for all of them. ## Request headers | Header | Required | Purpose | | ----------------- | --------------------------------- | ------------------------------------------------------------------------------------------- | | `X-Bunker-Token` | Yes (for authenticated endpoints) | The access credential β€” any of the token types below | | `X-Bunker-Tenant` | No | Selects the tenant by name in [multi-tenant](/pro/administration/multi-tenancy) deployments | If `X-Bunker-Tenant` is omitted, Databunker Pro derives the tenant from the **subdomain** of the request host (`acme.databunker.example.com` β†’ tenant `acme`). Requests to `localhost` or a bare host resolve to the **default** tenant. ## Credential hierarchy | Credential | Token type | Obtained via | Expiry | | ------------------- | ---------------------- | --------------------------------------- | ----------------------------------------------------------- | | Root token | `root` | Interactive setup or unattended install | Never | | Tenant access token | `root` (tenant-scoped) | `TenantCreate` | Never | | Role xtoken | `role` | `XTokenCreateForRole` | Default 10 minutes; capped by `max_xtoken_retention_period` | | User login xtoken | `login` | `XTokenCreateForUser` | Default 10 minutes; capped by `max_xtoken_retention_period` | | Bulk-unlock UUID | request gate | `BulkListUnlock` | 60 seconds | All tokens are stored **hashed** on the server β€” a token value is shown exactly once at creation time and cannot be recovered later. ### Root token The highest-privilege credential of the deployment, created once at installation: * **Interactive setup** β€” shown once on the setup completion screen. See [Generate admin credentials](/pro/installation/generate-admin-credentials). * **Unattended install** β€” returned by the `/autoinstall` endpoint, which is enabled only while the `DATABUNKER_SETUPKEY` environment variable is set. See [Unattended installation](/pro/installation/unattended-installation). Root tokens never expire. Use them for administration and automation, and prefer scoped role xtokens for application traffic. ### Tenant access token In multi-tenant deployments, `TenantCreate` returns an `xtoken` β€” the tenant administrator's credential. It behaves like a root token scoped to that tenant: ```bash theme={null} curl -X POST https://your-databunker/v2/TenantCreate \ -H "X-Bunker-Token: ROOT-ACCESS-TOKEN" \ -d '{"tenantname":"acme","tenantorg":"Acme Corp"}' ``` ```json theme={null} { "status": "ok", "xtoken": "TENANT-ACCESS-TOKEN" } ``` The tenant admin passes this token in `X-Bunker-Token`, together with `X-Bunker-Tenant: acme` (or the tenant subdomain). See [Multi-tenancy](/pro/administration/multi-tenancy). ### Role xtoken Scoped service credentials governed by [access-control policies](/pro/administration/access-control). Setup is three calls: ```bash theme={null} # 1. Create a role curl -X POST https://your-databunker/v2/RoleCreate \ -H "X-Bunker-Token: ROOT-ACCESS-TOKEN" \ -d '{"rolename":"support-desk"}' # 2. Attach a policy to the role curl -X POST https://your-databunker/v2/RoleLinkPolicy \ -H "X-Bunker-Token: ROOT-ACCESS-TOKEN" \ -d '{"roleid":1,"policyid":1}' # 3. Issue an xtoken for the role curl -X POST https://your-databunker/v2/XTokenCreateForRole \ -H "X-Bunker-Token: ROOT-ACCESS-TOKEN" \ -d '{"roleid":1,"finaltime":"7d"}' ``` ```json theme={null} { "status": "ok", "xtoken": "ROLE-XTOKEN" } ``` Without `finaltime` the xtoken expires after **10 minutes**. A supplied `finaltime` is capped by the `max_xtoken_retention_period` configuration policy. ### User login xtoken A short-lived credential that lets an end user act on **their own record only** (e.g. from the user privacy portal): ```bash theme={null} curl -X POST https://your-databunker/v2/XTokenCreateForUser \ -H "X-Bunker-Token: ROOT-ACCESS-TOKEN" \ -d '{"mode":"email","identity":"user@example.com"}' ``` ```json theme={null} { "status": "ok", "xtoken": "USER-LOGIN-XTOKEN", "token": "USER-TOKEN-UUID" } ``` Same expiry rules as role xtokens: 10 minutes by default, capped by `max_xtoken_retention_period`. For safety, a login xtoken **cannot** invoke `UserDelete`, `UserUpdate`, `UserPatch`, `AppdataUpdate`, or `AgreementCancel` on its own record β€” these self-service operations must go through an admin or a [user request workflow](/pro/api/overview) with approval. ### Bulk-unlock UUID Bulk read and delete operations are **denied by default** β€” an admin token alone is not enough. You must first obtain a short-lived unlock UUID, then pass it with the bulk call: ```bash theme={null} # Step 1: obtain the unlock UUID (valid for 60 seconds) curl -X POST https://your-databunker/v2/BulkListUnlock \ -H "X-Bunker-Token: ROOT-ACCESS-TOKEN" # β†’ { "status": "ok", "unlockuuid": "..." } # Step 2: use it in the bulk request curl -X POST https://your-databunker/v2/BulkListAllUsers \ -H "X-Bunker-Token: ROOT-ACCESS-TOKEN" \ -d '{"unlockuuid":"...","offset":0,"limit":100}' ``` The unlock UUID lives for **60 seconds** and may be reused within that window. It applies to `BulkList*`, `BulkDeleteTokens`, `UserSearch`, and the cross-tenant `System*` lookups. See [Select security](/pro/concepts/select-security) for the design rationale. ## Endpoint permission levels * **Public endpoints** β€” no token required: `UserPrelogin`, `UserLogin`, `CaptchaCreate`, `SharedRecordGet`, `TenantGetUIConf`. Calls to these are not written to the audit trail. * **Authenticated endpoints** β€” everything else requires `X-Bunker-Token` and passes policy evaluation: root tokens bypass policy checks, role xtokens are evaluated against their linked policies, and login xtokens are restricted to the user's own record. * **Main-tenant-only endpoints** β€” denied to sub-tenant admins even with a valid tenant token: `RoleCreate`, `RoleUpdate`, `PolicyCreate`, `PolicyUpdate`, `TenantListTenants`, `SystemGenerateWrappingKey`, and all cross-tenant `System*` operations. Failed authentication returns HTTP `403` with `{"status":"error","message":"Access denied"}` β€” see [Errors](/pro/api/errors). # Create access token for role Source: https://docs.databunker.org/pro/api/authentication/create-access-token-for-role /pro/api/openapi.yml post /v2/XTokenCreateForRole Creates an access token for a specific role # Create access token for user Source: https://docs.databunker.org/pro/api/authentication/create-access-token-for-user /pro/api/openapi.yml post /v2/XTokenCreateForUser Creates an access token for a specific user # Create bulk list unlock Source: https://docs.databunker.org/pro/api/bulk-operations/create-bulk-list-unlock /pro/api/openapi.yml post /v2/BulkListUnlock Creates an unlock mechanism for bulk list operations # Delete tokens in bulk Source: https://docs.databunker.org/pro/api/bulk-operations/delete-tokens-in-bulk /pro/api/openapi.yml post /v2/BulkDeleteTokens Deletes multiple tokens using the bulk unlock mechanism # List all audit events in bulk Source: https://docs.databunker.org/pro/api/bulk-operations/list-all-audit-events-in-bulk /pro/api/openapi.yml post /v2/BulkListAllAuditEvents Lists all audit events using the bulk unlock mechanism # List all user requests in bulk Source: https://docs.databunker.org/pro/api/bulk-operations/list-all-user-requests-in-bulk /pro/api/openapi.yml post /v2/BulkListAllUserRequests Lists all user requests using the bulk unlock mechanism with pagination # List all users in bulk Source: https://docs.databunker.org/pro/api/bulk-operations/list-all-users-in-bulk /pro/api/openapi.yml post /v2/BulkListAllUsers Lists all users using the bulk unlock mechanism with pagination # List specific users in bulk Source: https://docs.databunker.org/pro/api/bulk-operations/list-specific-users-in-bulk /pro/api/openapi.yml post /v2/BulkListUsers Lists specific users using the bulk unlock mechanism with user search criteria # List tokens in bulk Source: https://docs.databunker.org/pro/api/bulk-operations/list-tokens-in-bulk /pro/api/openapi.yml post /v2/BulkListTokens Lists tokens using the bulk unlock mechanism # List users in group in bulk Source: https://docs.databunker.org/pro/api/bulk-operations/list-users-in-group-in-bulk /pro/api/openapi.yml post /v2/BulkListGroupUsers Lists users in a specific group using the bulk unlock mechanism # Errors Source: https://docs.databunker.org/pro/api/errors Error response format, HTTP status codes, and a catalog of common error messages returned by the Databunker Pro API. Every error is returned as a JSON body with a fixed shape: ```json theme={null} { "status": "error", "message": "The user record was not found" } ``` Successful responses always include `"status": "ok"`. As a defensive pattern, check the JSON `status` field in addition to the HTTP status code. ## HTTP status codes | Code | Meaning | | ---- | -------------------------------------------------------------------------------------------------------- | | 400 | Bad request β€” malformed body, missing or invalid parameters, schema validation failure | | 403 | Access denied β€” missing/invalid API token, insufficient permissions, disabled feature, or license limit | | 404 | The referenced record was not found | | 409 | Conflict β€” duplicate record, name already in use, or operation conflicts with the record's current state | | 500 | Internal server error | Databunker Pro releases prior to the 2026-07 update returned HTTP `405` for most error conditions. If you run an older release, treat any non-2xx response as an error and rely on the JSON `status`/`message` fields. ## Common error messages The `message` field is human-readable. Representative messages per status code: ### 400 β€” Bad request | Message | Cause | | -------------------------------------------- | ------------------------------------------------------- | | `Missing API request parameters: profile` | A required request field was omitted (lists the fields) | | `Failed to decode the request body` | The body is not valid JSON | | `Bad UUID` | An identifier is not a valid UUID | | `The mode parameter has an incorrect format` | An enum-style parameter has an unexpected value | | `Failed to validate user schema: ...` | The profile fails the configured user record schema | | `The filedata parameter is not valid base64` | File upload payload is not base64-encoded | ### 403 β€” Access denied | Message | Cause | | ---------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------ | | `Access denied` | Missing/invalid `X-Bunker-Token`, or the token's policy denies the operation | | `API access denied` | Policy evaluation rejected the request | | `Record limit reached` | The license record cap was hit β€” new records cannot be created | | `License expired` | The installation license has expired | | `BulkListUsers is disabled` | The `list_users` configuration flag is off | | `The unlockuuid value was not found or is not valid` | The [bulk-unlock UUID](/pro/api/authentication#bulk-unlock-uuid) is missing, wrong, or past its 60-second lifetime | | `Only the main tenant admin can ...` | A main-tenant-only endpoint was called with a sub-tenant token | ### 404 β€” Not found | Message | Cause | | -------------------------------------- | --------------------------------------------- | | `The user record was not found` | No user matches the given `mode`/`identity` | | `Token not found` | The token UUID does not exist or has expired | | `The group record was not found` | Unknown group ID | | `The legal basis record was not found` | Unknown legal-basis `brief` | | `The API request was not found` | The `/v2/` endpoint name does not exist | ### 409 β€” Conflict | Message | Cause | | -------------------------------- | ----------------------------------------------------------------------------- | | `Duplicate index: email` | Another user already holds this unique index value (email/phone/login/custom) | | `The role record already exists` | Create called with a name that is already taken | | `Duplicate tenant name` | Tenant name already in use | | `This user request is closed` | Approve/cancel called on a request that is no longer open | ### 500 β€” Internal server error | Message | Cause | | ----------------------------------- | ----------------------------------------------------------------- | | `Internal error` / `Database error` | Unexpected server-side failure β€” check the server logs | | `Failed to decrypt the user record` | Storage-level failure (e.g. key mismatch) β€” check the server logs | Server-side error details (database errors, stack context) are **never** included in API responses β€” they are written to the server log and the audit trail only. ## Special cases * **`UserPrelogin` captcha failure** returns HTTP `200` with `{"status":"error","message":"captcha-error"}` β€” the user portal login flow consumes this in-body. Always check the `status` field on prelogin responses. * **Public endpoints** (`UserPrelogin`, `UserLogin`, `CaptchaCreate`, `SharedRecordGet`, `TenantGetUIConf`) require no token; all other endpoints return `403` without a valid one β€” see [Authentication](/pro/api/authentication). * **Unknown endpoint names** under `/v2/` return `404` with `The API request was not found`; unknown URL paths outside `/v2/` return `404` with `endpoint is missing`. # Delete a user file Source: https://docs.databunker.org/pro/api/file-storage/delete-a-user-file /pro/api/openapi.yml post /v2/FileDelete Removes a user file, deleting both the stored object and its metadata. # Get a user file Source: https://docs.databunker.org/pro/api/file-storage/get-a-user-file /pro/api/openapi.yml post /v2/FileGet Returns the decrypted content of a user file. The file is selected by `fileuuid` (preferred) or by `filename`. When selecting by `filename`, the most recently created file with that name is returned. At least one of `fileuuid` or `filename` is required. By default the content is returned as a base64-encoded `filedata` field inside a JSON response. Set `raw` to `true` to receive the decrypted bytes directly with the appropriate `Content-Type` and `Content-Disposition` headers (useful for direct downloads). # List user files Source: https://docs.databunker.org/pro/api/file-storage/list-user-files /pro/api/openapi.yml post /v2/FileListUserFiles Retrieves the metadata of all files owned by a user. File content is not returned. # Store a file for a user Source: https://docs.databunker.org/pro/api/file-storage/store-a-file-for-a-user /pro/api/openapi.yml post /v2/FileCreate Stores an encrypted file for a user. The file content is supplied as a base64-encoded `filedata` field. Each file is encrypted with a per-file key (wrapped by the user's record key) and stored in the configured object-storage backend (local disk, Amazon S3, Google Cloud Storage, or Azure Blob Storage). If the same content is uploaded again for the same user, the response sets `duplicate` to `true` and no new object is written. # Create multiple tokens in bulk Source: https://docs.databunker.org/pro/api/format-preserving-tokenization/create-multiple-tokens-in-bulk /pro/api/openapi.yml post /v2/TokenCreateBulk Creates multiple tokens for sensitive data # Create token for sensitive data Source: https://docs.databunker.org/pro/api/format-preserving-tokenization/create-token-for-sensitive-data /pro/api/openapi.yml post /v2/TokenCreate Creates a token for sensitive data like credit card numbers # Delete token Source: https://docs.databunker.org/pro/api/format-preserving-tokenization/delete-token /pro/api/openapi.yml post /v2/TokenDelete Deletes a token and its associated data # Get token data Source: https://docs.databunker.org/pro/api/format-preserving-tokenization/get-token-data /pro/api/openapi.yml post /v2/TokenGet Retrieves the original data for a given token # Add user to group Source: https://docs.databunker.org/pro/api/group-management/add-user-to-group /pro/api/openapi.yml post /v2/GroupAddUser Adds a user to a specific group with optional role assignment # Create a new group Source: https://docs.databunker.org/pro/api/group-management/create-a-new-group /pro/api/openapi.yml post /v2/GroupCreate Creates a new group for organizing users # Delete group Source: https://docs.databunker.org/pro/api/group-management/delete-group /pro/api/openapi.yml post /v2/GroupDelete Deletes a group # Get group information Source: https://docs.databunker.org/pro/api/group-management/get-group-information /pro/api/openapi.yml post /v2/GroupGet Retrieves information about a specific group # List all groups Source: https://docs.databunker.org/pro/api/group-management/list-all-groups /pro/api/openapi.yml post /v2/GroupListAllGroups Retrieves a list of all groups in the system # List user groups Source: https://docs.databunker.org/pro/api/group-management/list-user-groups /pro/api/openapi.yml post /v2/GroupListUserGroups Lists all groups for a specific user # Remove user from group Source: https://docs.databunker.org/pro/api/group-management/remove-user-from-group /pro/api/openapi.yml post /v2/GroupDeleteUser Removes a user from a specific group # Update group Source: https://docs.databunker.org/pro/api/group-management/update-group /pro/api/openapi.yml post /v2/GroupUpdate Updates an existing group # Create legal basis Source: https://docs.databunker.org/pro/api/legal-basis-management/create-legal-basis /pro/api/openapi.yml post /v2/LegalBasisCreate Creates a new legal basis for data processing # Delete legal basis Source: https://docs.databunker.org/pro/api/legal-basis-management/delete-legal-basis /pro/api/openapi.yml post /v2/LegalBasisDelete Deletes a legal basis # List legal basis agreements Source: https://docs.databunker.org/pro/api/legal-basis-management/list-legal-basis-agreements /pro/api/openapi.yml post /v2/LegalBasisListAgreements Lists all legal basis agreements in the system # Update legal basis Source: https://docs.databunker.org/pro/api/legal-basis-management/update-legal-basis /pro/api/openapi.yml post /v2/LegalBasisUpdate Updates an existing legal basis # API Overview Source: https://docs.databunker.org/pro/api/overview Databunker Pro is a privacy-compliant user data vault and tokenization engine that provides secure storage and management of user data with built-in privacy controls, consent management, and audit capabilities. ## API Documents for AI Assistants Feed these directly into your LLM or AI coding assistant for accurate, context-aware help when building integrations: * [OpenAPI Specification](https://github.com/securitybunker/databunkerpro-docs/blob/main/pro/api/openapi.yml) * [Full documentation (LLM-friendly)](https://docs.databunker.org/llms-full.txt) ## Key Features * **User Tokenization**: Create, update, and manage user profiles with privacy controls * **Consent Management**: Handle legal basis and user agreements for GDPR/DPDP compliance * **Format Preserving Tokenization**: Secure tokenization of sensitive data like credit cards * **File Storage**: Encrypted per-user file storage backed by local disk, Amazon S3, Google Cloud Storage, or Azure Blob Storage * **Audit Trail**: Complete audit logging of all data access and modifications * **Multi-tenant**: Support for multiple tenants with isolated data * **Role-based Access**: Fine-grained access control with policies and roles * **Bulk Operations**: Efficient bulk data operations with unlock mechanisms ## Authentication All API calls require authentication via the `X-Bunker-Token` header. For multi-tenant setups, use the `X-Bunker-Tenant` header to specify the tenant context. For the full credential hierarchy β€” root tokens, tenant tokens, role and user xtokens, and the bulk-unlock UUID β€” see the [Authentication reference](/pro/api/authentication). ### Multi-Tenant Usage Multi-tenancy is supported when Databunker Pro is configured to work with PostgreSQL database. **Note:** Databunker Pro supports both PostgreSQL and MySQL (Percona) as backend databases, but multi-tenancy requires PostgreSQL and is not available with MySQL. When using Databunker Pro in a multi-tenant environment: * **Single Tenant**: Omit the `X-Bunker-Tenant` header (default behavior) * **Multi-Tenant**: Include `X-Bunker-Tenant: your-tenant-name` header **Example:** ```bash theme={null} # Single tenant curl -X POST http://localhost:3000/v2/UserCreate \ -H "X-Bunker-Token: your-token" \ -d '{"profile":{"login":"user1"}}' # Multi-tenant curl -X POST http://localhost:3000/v2/UserCreate \ -H "X-Bunker-Token: your-token" \ -H "X-Bunker-Tenant: acme-corp" \ -d '{"profile":{"login":"user1"}}' ``` ## Base URL The API is available at `/v2/` endpoint with all requests using POST method. ## Error Handling Every error is returned as `{"status":"error","message":"..."}` with a conventional HTTP status code (400/403/404/409/500). See the full [Errors reference](/pro/api/errors) for the status-code table and a catalog of common messages. ## Pagination List endpoints accept `offset`/`limit` in the request body and return a `{status, total, rows}` envelope. See the [Pagination reference](/pro/api/pagination). # Pagination Source: https://docs.databunker.org/pro/api/pagination How list endpoints paginate results in Databunker Pro β€” offset/limit parameters, the response envelope, and a worked example. List endpoints use **offset/limit pagination**. Parameters are passed in the JSON request body: | Parameter | Type | Default | Notes | | --------- | ------- | ------- | --------------------------------------------------------------- | | `offset` | integer | `0` | Number of records to skip | | `limit` | integer | `10` | Page size. Values below `1` or above `100` are treated as `100` | The `limit` cap is silent: requesting `limit: 500` (or an invalid value) returns up to **100** rows without an error. Always read `total` from the response instead of assuming your requested page size was honored. ## Response envelope All list endpoints share the same envelope: ```json theme={null} { "status": "ok", "total": 1543, "rows": [ { "...": "..." } ] } ``` `total` is the **complete record count**, not the number of rows in the current page β€” use it to compute how many pages to fetch. ## Paginated endpoints | Endpoint | Notes | | ----------------------------- | ------------------------------------------------------------------- | | `BulkListUsers` | Requires an [unlock UUID](/pro/api/authentication#bulk-unlock-uuid) | | `BulkListAllUsers` | Requires an unlock UUID; needs the `list_users` config flag | | `BulkListGroupUsers` | Requires an unlock UUID | | `BulkListAllUserRequests` | Requires an unlock UUID | | `BulkListAllAuditEvents` | Requires an unlock UUID | | `UserRequestListUserRequests` | Per-user request list | | `AuditListUserEvents` | Per-user audit trail | | `TenantListTenants` | Main-tenant admin only | Other `List*` endpoints (`GroupListAllGroups`, `PolicyListAllPolicies`, `AppdataListUserAppNames`, `FileListUserFiles`, `SessionListUserSessions`, etc.) return the **full result set** in one response β€” their collections are expected to stay small. Cursor-based pagination is not available β€” offset/limit is the only mechanism. ## Example: paging through all users Bulk listing is gated by a short-lived unlock UUID (see [Authentication](/pro/api/authentication#bulk-unlock-uuid)). Fetch the unlock, then iterate: ```bash theme={null} # Obtain an unlock UUID (valid for 60 seconds) UNLOCK=$(curl -s -X POST https://your-databunker/v2/BulkListUnlock \ -H "X-Bunker-Token: ROOT-ACCESS-TOKEN" | jq -r .unlockuuid) # Page 1 (records 0-99) curl -X POST https://your-databunker/v2/BulkListAllUsers \ -H "X-Bunker-Token: ROOT-ACCESS-TOKEN" \ -d "{\"unlockuuid\":\"$UNLOCK\",\"offset\":0,\"limit\":100}" # Page 2 (records 100-199) curl -X POST https://your-databunker/v2/BulkListAllUsers \ -H "X-Bunker-Token: ROOT-ACCESS-TOKEN" \ -d "{\"unlockuuid\":\"$UNLOCK\",\"offset\":100,\"limit\":100}" ``` If a long export outlives the 60-second unlock window, request a fresh `unlockuuid` and continue from the same `offset`. # Create a new policy Source: https://docs.databunker.org/pro/api/policy-management/create-a-new-policy /pro/api/openapi.yml post /v2/PolicyCreate Creates a new access control policy # Get policy information Source: https://docs.databunker.org/pro/api/policy-management/get-policy-information /pro/api/openapi.yml post /v2/PolicyGet Retrieves information about a specific policy # List all policies Source: https://docs.databunker.org/pro/api/policy-management/list-all-policies /pro/api/openapi.yml post /v2/PolicyListAllPolicies Retrieves a list of all policies in the system # Update a policy Source: https://docs.databunker.org/pro/api/policy-management/update-a-policy /pro/api/openapi.yml post /v2/PolicyUpdate Updates an existing access control policy # Create processing activity Source: https://docs.databunker.org/pro/api/processing-activity-management/create-processing-activity /pro/api/openapi.yml post /v2/ProcessingActivityCreate Creates a new processing activity # Delete processing activity Source: https://docs.databunker.org/pro/api/processing-activity-management/delete-processing-activity /pro/api/openapi.yml post /v2/ProcessingActivityDelete Deletes a processing activity # Link processing activity to legal basis Source: https://docs.databunker.org/pro/api/processing-activity-management/link-processing-activity-to-legal-basis /pro/api/openapi.yml post /v2/ProcessingActivityLinkLegalBasis Links a processing activity to a legal basis # List processing activities Source: https://docs.databunker.org/pro/api/processing-activity-management/list-processing-activities /pro/api/openapi.yml post /v2/ProcessingActivityListActivities Lists all processing activities in the system # Unlink processing activity from legal basis Source: https://docs.databunker.org/pro/api/processing-activity-management/unlink-processing-activity-from-legal-basis /pro/api/openapi.yml post /v2/ProcessingActivityUnlinkLegalBasis Unlinks a processing activity from a legal basis # Update processing activity Source: https://docs.databunker.org/pro/api/processing-activity-management/update-processing-activity /pro/api/openapi.yml post /v2/ProcessingActivityUpdate Updates an existing processing activity # Create a new role Source: https://docs.databunker.org/pro/api/role-management/create-a-new-role /pro/api/openapi.yml post /v2/RoleCreate Creates a new role for access control # Link policy to role Source: https://docs.databunker.org/pro/api/role-management/link-policy-to-role /pro/api/openapi.yml post /v2/RoleLinkPolicy Links a policy to a role for access control # Update role Source: https://docs.databunker.org/pro/api/role-management/update-role /pro/api/openapi.yml post /v2/RoleUpdate Updates an existing role # Delete session Source: https://docs.databunker.org/pro/api/session-management/delete-session /pro/api/openapi.yml post /v2/SessionDelete Deletes a user session # Get session Source: https://docs.databunker.org/pro/api/session-management/get-session /pro/api/openapi.yml post /v2/SessionGet Retrieves information about a specific session # List user sessions Source: https://docs.databunker.org/pro/api/session-management/list-user-sessions /pro/api/openapi.yml post /v2/SessionListUserSessions Lists all sessions for a specific user # Upsert session Source: https://docs.databunker.org/pro/api/session-management/upsert-session /pro/api/openapi.yml post /v2/SessionUpsert Creates or updates a user session # Create shared record Source: https://docs.databunker.org/pro/api/shared-records/create-shared-record /pro/api/openapi.yml post /v2/SharedRecordCreate Creates a shared record for a user with specific fields # Get shared record Source: https://docs.databunker.org/pro/api/shared-records/get-shared-record /pro/api/openapi.yml post /v2/SharedRecordGet Retrieves a shared record by its UUID # Delete user profiles across all tenants Source: https://docs.databunker.org/pro/api/system-operations/delete-user-profiles-across-all-tenants /pro/api/openapi.yml post /v2/SystemDeleteUserProfiles Deletes all profiles for a user identified by email, phone, login, custom field, or token across all tenants. An optional `tenantid` or `tenantname` parameter can restrict deletion to a single tenant. The `token` mode is only allowed when `tenantid` or `tenantname` is specified. Only accessible by the main tenant admin (tenantID=1). Requires a bulk list unlock UUID obtained from `BulkListUnlock`. Deleted records are preserved in version history and can be restored with `SystemRestoreUserProfile`. # Generate wrapping key from Shamir's Secret Sharing keys Source: https://docs.databunker.org/pro/api/system-operations/generate-wrapping-key-from-shamirs-secret-sharing-keys /pro/api/openapi.yml post /v2/SystemGenerateWrappingKey Generates a wrapping key from three Shamir's Secret Sharing keys # Get system statistics Source: https://docs.databunker.org/pro/api/system-operations/get-system-statistics /pro/api/openapi.yml post /v2/SystemGetSystemStats Retrieves system statistics including user counts, tenant counts, and other metrics # Get user HTML report Source: https://docs.databunker.org/pro/api/system-operations/get-user-html-report /pro/api/openapi.yml post /v2/SystemGetUserHTMLReport Generates an HTML report for a specific user # Get user profiles across all tenants Source: https://docs.databunker.org/pro/api/system-operations/get-user-profiles-across-all-tenants /pro/api/openapi.yml post /v2/SystemGetUserProfiles Retrieves all profiles for a user identified by email, phone, login, or custom field across all tenants. Only accessible by the main tenant admin (tenantID=1). The `token` mode is not supported. Requires a bulk list unlock UUID obtained from `BulkListUnlock`. # Get user report Source: https://docs.databunker.org/pro/api/system-operations/get-user-report /pro/api/openapi.yml post /v2/SystemGetUserReport Generates a detailed report for a specific user # Restore a deleted user profile Source: https://docs.databunker.org/pro/api/system-operations/restore-a-deleted-user-profile /pro/api/openapi.yml post /v2/SystemRestoreUserProfile Restores a previously deleted user profile for a specific tenant from version history. The caller must provide the user `token` and either `tenantid` or `tenantname`. Only accessible by the main tenant admin (tenantID=1). Requires a bulk list unlock UUID obtained from `BulkListUnlock`. # Search user profiles across all tenants Source: https://docs.databunker.org/pro/api/system-operations/search-user-profiles-across-all-tenants /pro/api/openapi.yml post /v2/SystemSearchUserProfiles Fuzzy-searches for user profiles across all tenants by identity. The search mode is auto-detected from the `identity` value: - If `identity` contains `@`, it is treated as an email search - Otherwise it searches across login, phone, and custom fields Only accessible by the main tenant admin (tenantID=1). Requires a bulk list unlock UUID obtained from `BulkListUnlock`. # Create a new tenant Source: https://docs.databunker.org/pro/api/tenant-management/create-a-new-tenant /pro/api/openapi.yml post /v2/TenantCreate Creates a new tenant for multi-tenant setups # Get tenant information Source: https://docs.databunker.org/pro/api/tenant-management/get-tenant-information /pro/api/openapi.yml post /v2/TenantGet Retrieves information about a specific tenant # List all tenants Source: https://docs.databunker.org/pro/api/tenant-management/list-all-tenants /pro/api/openapi.yml post /v2/TenantListTenants Retrieves a list of all tenants in the system # Update tenant information Source: https://docs.databunker.org/pro/api/tenant-management/update-tenant-information /pro/api/openapi.yml post /v2/TenantUpdate Updates information about a specific tenant # Approve user request Source: https://docs.databunker.org/pro/api/user-tokenization/approve-user-request /pro/api/openapi.yml post /v2/UserRequestApprove Approves a pending user request # Cancel user request Source: https://docs.databunker.org/pro/api/user-tokenization/cancel-user-request /pro/api/openapi.yml post /v2/UserRequestCancel Cancels a pending user request # Create a new user token Source: https://docs.databunker.org/pro/api/user-tokenization/create-a-new-user-token /pro/api/openapi.yml post /v2/UserCreate Creates a new user token with profile information and optional group/role assignment # Create multiple users in bulk Source: https://docs.databunker.org/pro/api/user-tokenization/create-multiple-users-in-bulk /pro/api/openapi.yml post /v2/UserCreateBulk Creates multiple users with their profiles and group information # Delete user Source: https://docs.databunker.org/pro/api/user-tokenization/delete-user /pro/api/openapi.yml post /v2/UserDelete Deletes a user and their associated data # Get user information Source: https://docs.databunker.org/pro/api/user-tokenization/get-user-information /pro/api/openapi.yml post /v2/UserGet Retrieves user information by login, token, or other identifiers # Get user request Source: https://docs.databunker.org/pro/api/user-tokenization/get-user-request /pro/api/openapi.yml post /v2/UserRequestGet Retrieves information about a specific user request # List user requests Source: https://docs.databunker.org/pro/api/user-tokenization/list-user-requests /pro/api/openapi.yml post /v2/UserRequestListUserRequests Lists all requests for a specific user # List user versions Source: https://docs.databunker.org/pro/api/user-tokenization/list-user-versions /pro/api/openapi.yml post /v2/UserListVersions Lists all versions of a user's profile # Patch user profile using JSON Patch Source: https://docs.databunker.org/pro/api/user-tokenization/patch-user-profile-using-json-patch /pro/api/openapi.yml post /v2/UserPatch Updates user profile using JSON Patch operations (RFC 6902) # Request user deletion Source: https://docs.databunker.org/pro/api/user-tokenization/request-user-deletion /pro/api/openapi.yml post /v2/UserDeleteRequest Creates a deletion request for a user (requires approval) # Request user patch Source: https://docs.databunker.org/pro/api/user-tokenization/request-user-patch /pro/api/openapi.yml post /v2/UserPatchRequest Creates a patch request for a user (requires approval) # Request user update Source: https://docs.databunker.org/pro/api/user-tokenization/request-user-update /pro/api/openapi.yml post /v2/UserUpdateRequest Creates an update request for a user (requires approval) # Search users Source: https://docs.databunker.org/pro/api/user-tokenization/search-users /pro/api/openapi.yml post /v2/UserSearch Searches for users using fuzzy matching. The search mode is auto-detected from the `identity` value: - If `identity` contains `@`, it is treated as an email search - Otherwise it searches across login, phone, and custom fields # Update user profile Source: https://docs.databunker.org/pro/api/user-tokenization/update-user-profile /pro/api/openapi.yml post /v2/UserUpdate Updates user profile information # AWS Cognito vs Databunker Pro β€” PII Vault & Tokenization Source: https://docs.databunker.org/pro/comparisons/aws-cognito-alternative LLM-built auth plus Databunker Pro β€” the modern replacement for AWS Cognito, with self-hosted PII vaulting and compliance built in. AWS Cognito was built in 2014, when standing up authentication β€” sign-in, password reset, OAuth, SSO federation, JWT issuance β€” was genuinely a multi-month project. That world is gone. With LLM-assisted development and modern auth libraries, the auth layer is now an afternoon's work. What's actually hard in 2026 is the part Cognito doesn't solve: **encrypting PII at rest, tokenising sensitive fields, tracking consent, handling DSARs, proving compliance to an auditor, and meeting cross-border data-localisation laws.** **Databunker Pro + LLM-built auth** is the modern replacement for Cognito. You build the auth glue once, in your own codebase, with full control. Databunker Pro handles everything Cognito can't: the PII vault, format-preserving tokenization, consent management, audit, and compliance β€” self-hosted in any cloud, on-premises, or across jurisdictions. ## Authentication is now an afternoon, not a project LLMs (Claude, Cursor, Copilot, GitHub Codespaces) scaffold a complete auth system from a single prompt: email/password sign-up, Google / Microsoft / Apple SSO, JWT sessions with refresh, password reset, MFA via TOTP or magic links, account recovery. Pair that with a well-maintained library and you have a production-ready auth layer in hours, not months. A non-exhaustive list of mature, well-documented auth libraries that pair cleanly with LLM-driven implementation: | Stack | Library | | -------------- | -------------------------------------------------------------------------------------------------------------------------- | | Node / Next.js | [NextAuth.js / Auth.js](https://authjs.dev/), [Lucia](https://lucia-auth.com/), [Passport.js](https://www.passportjs.org/) | | Python | [Authlib](https://authlib.org/), [FastAPI Users](https://fastapi-users.github.io/fastapi-users/) | | Go | [Ory Kratos](https://www.ory.sh/kratos/), [GoTrue](https://github.com/supabase/gotrue) | | Multi-language | [Keycloak](https://www.keycloak.org/), [Ory](https://www.ory.sh/), [Authelia](https://www.authelia.com/) | Any of these, combined with an LLM that knows your codebase, produces a working auth system the same day you start. The deliverable is yours β€” no per-MAU bill, no vendor lock-in, no AWS dependency. ## What auth doesn't solve β€” and Databunker Pro does The auth layer issues identity tokens. It does **not** answer: * **Where do you store your users' PII so it isn't exposed in logs, backups, or a SQL injection?** * **How do you tokenise credit-card numbers to shrink PCI scope?** * **How do you fulfil a GDPR / DPDPA right-to-erasure request across every system that holds the user's data?** * **How do you prove to an auditor that every PII access was authorised and logged?** * **How do you keep Indian users' PII in India, Russian users' PII in Russia, and EU users' PII in the EU β€” all simultaneously?** These are the hard problems. Databunker Pro is built for them: * **[PII Vault](/pro/get-started/pii-vault)** β€” AES-256 per-record encryption; the application stores only UUID tokens, never PII. * **[Format-preserving tokenization](/pro/concepts/tokenization)** β€” Luhn-valid credit-card tokens, integer tokens, timestamp tokens. Real PCI-scope reduction. * **Consent management** β€” legal-basis tracking, user agreements, processing-activity records aligned with GDPR / DPDPA. * **DPO operations** β€” DSAR fulfilment, right-to-erasure, data-portability via the separate [Databunker DPO product](https://databunker.org/use-case/dpo-management-portal/). * **Audit trail** β€” per-record, per-field, with encrypted PII context. See [Access control](/pro/administration/access-control). * **[Multi-tenancy](/pro/administration/multi-tenancy)** β€” PostgreSQL row-level security; cryptographic per-domain isolation. * **[Record versioning](/pro/concepts/record-versioning)** β€” immutable history for every user record. * **[Fuzzy search](/pro/concepts/fuzzy-search)** β€” typo-tolerant search on encrypted data. * **[Shared records](/pro/concepts/shared-records)** β€” time-limited UUID references for safe cross-system sharing. * **[Shamir secret sharing](/pro/administration/shamir-keys)** β€” master-key recovery split across multiple custodians. * **BYOK / HYOK** β€” wrapping key in Kubernetes secret, AWS KMS, HashiCorp Vault, or hardware HSM. * **[Multi-jurisdiction deployment](/pro/concepts/global-deployment)** β€” one vault per jurisdiction (India, Russia, Turkey, EU, etc.) β€” a topology Cognito cannot match because Cognito is AWS-bound. * **Self-hosted** β€” deploy on any cloud, on-premises, in a sovereign region, or inside a customer's tenant. * **[Predictable pricing](/pro/get-started/performance)** β€” per-instance license, flat regardless of user count. No per-MAU bill. ## Reference architecture ```text theme={null} [ User ] ─── sign-in ───► [ Your auth layer (NextAuth / Lucia / Ory / Keycloak / ...) ] β”‚ Built once with LLM assistance. Issues JWT / session. β”‚ β–Ό [ Your application ] β”‚ β–Ό [ Databunker Pro ] AES-256 encrypted vault Tokenization Β· CRBAC Β· audit Self-hosted, any region ``` The application database only ever stores: a user identifier, a Databunker `user_token`, and any non-PII business data. PII lives in the vault. Auth lives in your own code. ## Comparison table | Capability | AWS Cognito | Databunker Pro + your auth | | ------------------------------------------- | ---------------------------------------------------------- | ------------------------------------------------------------------------------------ | | **Primary purpose** | Auth + user directory | PII vault, tokenization, consent, compliance | | **Where auth lives** | Managed AWS service | In your codebase (LLM-built, mature library) | | **Where PII lives** | Cognito user attributes (AWS) | Databunker Pro vault (your infra, any cloud) | | **PII encryption** | AWS-managed KMS at the user-pool level | AES-256 per record, FIPS 140-2, customer-controlled keys | | **Tokenization (UUID + format-preserving)** | ❌ | βœ… Native; shrinks PCI scope | | **Consent management & legal basis** | ❌ | βœ… Native (GDPR / DPDPA aligned) | | **Right-to-erasure** | `AdminDeleteUser` (PII in logs/backups still your problem) | Single API call; audit-bounded; record-versioning aware | | **Audit trail** | CloudTrail (API-level) | Per-record, per-field, with encrypted PII context | | **Fuzzy search on encrypted data** | ❌ | βœ… | | **Record versioning** | ❌ | βœ… | | **Customer-held keys (BYOK / HYOK)** | KMS CMK option, AWS-bound | K8s secret, AWS KMS, HashiCorp Vault, or hardware HSM | | **Multi-tenancy** | Separate user pools | Native PostgreSQL RLS | | **Deployment** | AWS only | Any cloud, on-prem, sovereign region, customer tenant | | **Data residency** | AWS regions | Any region; [multi-jurisdiction topology](/pro/concepts/global-deployment) supported | | **Vendor lock-in** | AWS | None β€” Docker / Helm artifacts | | **Pricing model** | Per MAU above the free tier | Per-instance license, flat | | **Future flexibility** | Constrained by what AWS adds to Cognito | Your codebase β€” change auth library, add MFA mode, swap SSO provider any time | ## Migration from Cognito The honest practical answer: **Cognito does not allow exporting password hashes**, so a migration is necessarily a forced-reset event. The standard playbook: 1. **Stand up Databunker Pro** in your target environment (Docker / Helm). 2. **Build the replacement auth layer** in your codebase using an LLM and the library of your choice (NextAuth, Lucia, Ory, Keycloak, etc.). Wire it to Databunker Pro for the user record. 3. **Export the Cognito user list** β€” emails, attributes, group memberships β€” via `ListUsers`. 4. **Bulk-import into Databunker Pro** using [`UserCreateBulk`](/pro/get-started/performance) β€” at \~1,700 records/sec on a single instance, a typical Cognito directory imports in minutes. 5. **Migration window**: switch the auth layer to your replacement and force a one-time password reset email to every user (unavoidable β€” Cognito does not expose hashes). 6. **Decommission the Cognito user pool** once the population has migrated. For organisations with strict downtime / UX constraints, a **dual-running window** (Cognito for existing users, new auth + Databunker for new ones, slow migration over weeks) is preferred. Databunker Pro's bulk import and multi-tenancy support this naturally. ## Code examples ### Sign-up: auth in your codebase, PII in Databunker ```javascript theme={null} // 1. User signs up via your auth layer (NextAuth / Lucia / Ory / etc.) // Your auth issues a session and gives you the verified email. // 2. Store PII in Databunker β€” get back a safe UUID token const response = await axios.post('https://your-databunker/v2/UserCreate', { profile: { email: form.email, first: form.firstName, last: form.lastName, phone: form.phone, address: form.address, dob: form.dateOfBirth, } }, { headers: { 'X-Bunker-Token': process.env.DATABUNKER_API_KEY } }); const userToken = response.data.token; // 3. Store only (userId, userToken) in your app DB β€” zero PII anywhere outside the vault await db.query( 'INSERT INTO users (id, databunker_token) VALUES ($1, $2)', [authUser.id, userToken] ); ``` If your application database gets breached, attackers see only opaque UUIDs β€” no PII, no contact data, no addresses. ### Format-preserving credit-card tokenization Cognito has no concept of this. Databunker Pro tokenises a real card number into a Luhn-valid token that passes format validation in downstream systems β€” so legacy fraud / payment / risk systems keep working without ever seeing the real card. ```bash theme={null} curl -X POST https://your-databunker/v2/TokenCreate \ -H "X-Bunker-Token: YOUR_API_KEY" \ -d '{ "record": "4532015112830366", "tokentype": "creditcard", "slidingtime": "30d", "unique": true }' ``` ```json theme={null} { "status": "ok", "tokenuuid": "550e8400-e29b-41d4-a716-446655440000", "tokenbase": "4024007186539112" } ``` `tokenbase` passes Luhn checks and 16-digit format validation, but maps to no real card. PCI audit scope shrinks to the systems that genuinely need detokenisation. ## The bottom line Cognito was the right answer when authentication was a hard build. With LLM-assisted development, auth is an afternoon's work in your own codebase β€” and **you keep the code, the keys, the deployment, and the data**. Pair that with Databunker Pro and you get the secure user storage, tokenization, consent management, audit, and cross-jurisdiction sovereignty that Cognito was never designed to provide. The result: no per-MAU bill, no AWS lock-in, full control over your users' PII, and a compliance posture that holds up in a regulator review. # Custom PII Vault vs Databunker Pro β€” Build or Buy? Source: https://docs.databunker.org/pro/comparisons/custom-solution-alternative What it actually takes to build a PII vault from scratch β€” and why most teams underestimate the effort by 10x. When teams first encounter the PII storage problem, the instinct is often: "We'll build it ourselves. It's just encryption and a database." That's how it starts. Then come the edge cases, the compliance requirements, and the features you didn't know you needed until an auditor asked for them. **Databunker Pro gives you a production-ready PII vault in a day.** Building the equivalent yourself takes months of engineering β€” and the ongoing maintenance never stops. ## What looks simple at first A basic encrypted user store seems straightforward: ```python theme={null} import json from cryptography.fernet import Fernet key = Fernet.generate_key() cipher = Fernet(key) def store_user(db, user_data): encrypted = cipher.encrypt(json.dumps(user_data).encode()) token = str(uuid.uuid4()) db.execute("INSERT INTO users (token, data) VALUES (%s, %s)", (token, encrypted)) return token def get_user(db, token): row = db.execute("SELECT data FROM users WHERE token = %s", (token,)).fetchone() return json.loads(cipher.decrypt(row[0])) ``` That's maybe 20 lines. Ship it. Done. Except it's not done. Here's what you'll need to build next. ## What you'll actually need to build ### 1. Key management Your encryption key is a single point of failure. You need: * A wrapping key to protect the master key * Key rotation without re-encrypting every record * A recovery mechanism if the key is lost (Shamir's secret sharing or similar) * Secure key storage that isn't just an environment variable Databunker Pro handles this with a master key, wrapping key rotation via API, and Shamir key sharing for recovery β€” built in from day one. ### 2. Searchable encrypted records Your first implementation can look up users by token. But then someone needs to find a user by email. Or phone number. Now you need: * A secure hash-based search index * Indexes that don't leak plaintext but still allow lookups * Support for multiple lookup fields (email, phone, login, custom fields) ```bash theme={null} # Databunker Pro β€” look up by email, phone, or token curl -X POST https://your-databunker/v2/UserGet \ -H "X-Bunker-Token: YOUR_API_KEY" \ -d '{"mode": "email", "identity": "john@example.com"}' curl -X POST https://your-databunker/v2/UserGet \ -H "X-Bunker-Token: YOUR_API_KEY" \ -d '{"mode": "phone", "identity": "+1-555-123-4567"}' ``` Building a secure search index that doesn't leak data is a research-level problem. Databunker Pro uses hash-based lookups that enable search without exposing plaintext. ### 3. Tokenization engine Beyond user profiles, you need to tokenize individual fields β€” credit card numbers, SSNs, health identifiers. And the tokens need to: * Preserve format for downstream systems (Luhn-valid card numbers, same-length strings) * Support deduplication (same input produces same token) * Have configurable expiration * Handle bulk operations at scale ```bash theme={null} # Databunker Pro β€” format-preserving credit card tokenization curl -X POST https://your-databunker/v2/TokenCreate \ -H "X-Bunker-Token: YOUR_API_KEY" \ -d '{ "record": "4532015112830366", "tokentype": "creditcard", "slidingtime": "30d", "unique": true }' ``` ```json theme={null} { "status": "ok", "tokenuuid": "550e8400-e29b-41d4-a716-446655440000", "tokenbase": "4024007186539112" } ``` Building a format-preserving tokenization engine that passes Luhn validation and handles millions of records is a significant engineering effort on its own. ### 4. Consent management GDPR Article 6 and the DPDP Act require you to record the legal basis for processing each person's data. You need: * A consent store linked to each user record * Support for multiple consent types (marketing, analytics, data sharing) * Consent withdrawal tracking * Timestamped audit trail of consent changes Most custom implementations skip this entirely β€” until the first compliance audit. ### 5. Audit trail Every access, modification, and deletion of PII needs to be logged. Not application logs β€” a tamper-resistant audit trail that: * Records who accessed what data, when, and why * Encrypts PII within the audit events themselves * Is queryable by a DPO or auditor * Can't be modified or deleted by application code ### 6. Data subject requests GDPR and DPDP Act give users the right to access, correct, and delete their data. You need: * **Right to access** β€” return all data you hold for a specific person * **Right to erasure** β€” delete everything for one user across all stores * **Right to portability** β€” export a user's data in a machine-readable format * **Right to rectification** β€” update a user's data across all linked records ```javascript theme={null} // Databunker Pro β€” full erasure in one call await axios.post('https://your-databunker/v2/UserDelete', { mode: 'token', identity: userToken }, { headers: { 'X-Bunker-Token': process.env.DATABUNKER_API_KEY } }); ``` In a custom solution, you need to track every table, every cache, every log file, and every downstream system that might contain a copy of a user's PII. ### 7. Record versioning and expiration Regulators may ask: "What data did you hold for this user six months ago?" You need: * Version history for every user record * Ability to retrieve a specific version * Automatic expiration (sliding and absolute TTLs) for data minimization * Proof that expired records were actually deleted ### 8. Multi-tenancy If you serve multiple customers or operate in multiple regions, you need tenant isolation: * Data from tenant A must never be visible to tenant B * Queries must be scoped by tenant at the database level (not just application logic) * Each tenant may need separate encryption keys Databunker Pro implements this with PostgreSQL row-level security β€” true database-level isolation, not application-layer filtering that a bug can bypass. ### 9. Access control Different services and team members need different levels of access: * Role-based policies (admin, read-only, tokenize-only) * API token management with scoped permissions * Rate limiting and abuse prevention ### 10. DPO portal Your Data Protection Officer needs a UI to handle data subject requests, review audit logs, and demonstrate compliance. Building an admin portal is another project entirely. ## The real cost comparison | | Custom solution | Databunker Pro | | ---------------------------------- | ----------------------------------------- | ----------------------------------------- | | **Initial build** | 3-6 months of senior engineering | Deploy in a day | | **Encryption + key management** | Build from scratch | Built-in (AES-256, Shamir, key rotation) | | **Searchable encrypted records** | Research-level problem | Built-in hash-based indexes | | **Format-preserving tokenization** | Significant engineering effort | One API call | | **Consent management** | Usually skipped, then rushed before audit | Built-in | | **Audit trail** | Custom implementation | Built-in, compliance-ready | | **Data subject requests** | Manual process across all data stores | Single API calls | | **Record versioning** | Custom implementation | Built-in | | **Auto-expiration** | Custom cron jobs and cleanup logic | Built-in TTLs | | **Multi-tenancy** | Application-layer filtering (bug-prone) | PostgreSQL row-level security | | **DPO portal** | Separate project | Built-in | | **Ongoing maintenance** | Your team, indefinitely | Managed upgrades | | **Compliance confidence** | Hope it holds up in an audit | Designed for GDPR, DPDP Act, HIPAA, SOC 2 | ## The hidden costs of building your own Beyond the initial build, a custom PII vault creates ongoing costs that teams rarely budget for: * **Security reviews** β€” every change to the encryption layer needs a security review * **Penetration testing** β€” custom crypto implementations are high-value targets * **Compliance updates** β€” new regulations (DPDP Act, state privacy laws) require new features * **Key rotation incidents** β€” when something goes wrong with key management at 2 AM * **Staff turnover** β€” the engineer who built the vault leaves, and nobody fully understands the code * **Audit preparation** β€” weeks of work assembling evidence for each compliance audit ## When a custom solution makes sense Building your own PII vault might be justified if: * You have unique requirements that no existing solution can meet * You have a dedicated security engineering team with cryptography expertise * You're willing to maintain the solution for years, including compliance updates * Your scale requires a fundamentally different architecture For most teams, those conditions don't apply. The PII vault is not where you want to differentiate β€” it's plumbing that needs to work correctly and compliantly so you can focus on your actual product. ## The bottom line The gap between a basic encrypted database and a production-ready PII vault is enormous. It includes key management, searchable encryption, tokenization, consent tracking, audit trails, data subject request handling, record versioning, multi-tenancy, access control, and a DPO portal. Teams that start building their own typically discover this gap six months in β€” after the first compliance audit, or the first data subject request they can't fulfill. Databunker Pro gives you all of this out of the box. Deploy it in a day, and spend your engineering time on the product your customers actually pay for. # HashiCorp Vault vs Databunker Pro β€” PII Storage & Compliance Source: https://docs.databunker.org/pro/comparisons/hashicorp-vault-alternative HashiCorp Vault manages infrastructure secrets. Databunker Pro is a PII vault purpose-built for personal data protection, tokenization, and privacy compliance. HashiCorp Vault is an infrastructure secrets manager β€” it stores API keys, database credentials, TLS certificates, and encryption keys. It's excellent at that job. But when teams try to use it as a PII vault for personal data, they quickly hit its limits. **Databunker Pro is purpose-built for PII.** It stores, encrypts, and tokenizes user records β€” names, emails, SSNs, credit cards, health data β€” with built-in consent management, audit trails, a DPO portal, and regulatory compliance out of the box. Vault was never designed for any of that. ## Vault is for infrastructure secrets, not personal data HashiCorp Vault solves a specific problem well: managing machine-to-machine secrets. It rotates database passwords, issues short-lived TLS certificates, and encrypts application data via its Transit engine. DevOps and platform teams rely on it for good reason. But PII is not an infrastructure secret. Personal data has regulatory requirements that Vault doesn't address: * **Data subject access requests** β€” a user asks "what data do you have on me?" Vault has no concept of a user profile or a way to retrieve all data belonging to one person. * **Right to erasure** β€” deleting all PII for one user across your system. In Vault, you'd have to track every secret path where you stored each user's data and delete them individually. * **Consent and legal basis tracking** β€” GDPR and DPDP Act require you to record why you're processing each person's data. Vault has no consent model. * **Data minimization** β€” storing only what's necessary, with automatic expiration. Vault secrets can have TTLs, but there's no concept of user record lifecycle management. * **Audit for compliance** β€” Vault logs access events, but not in a format an auditor or DPO can use to demonstrate privacy compliance. ## What Databunker Pro gives you that Vault doesn't Databunker Pro is a **complete PII protection platform**, not a generic secrets store adapted for personal data: * **User-centric data model** β€” store complete user profiles as JSON, look them up by email, phone, login, or token * **Format-preserving tokenization** β€” Luhn-valid credit card tokens, integer tokens, timestamp tokens β€” not just opaque UUIDs * **Consent management** β€” track legal basis, user agreements, and processing operations for GDPR/DPDP Act * **DPO portal** β€” built-in interface for Data Protection Officers to handle access, erasure, and portability requests * **Record versioning** β€” full version history for every user record, not just current state * **Auto-expiration** β€” sliding and absolute TTLs for automatic data deletion (data minimization by design) * **Fuzzy search** β€” search encrypted PII records without decrypting the database * **Multi-tenancy** β€” native row-level isolation in PostgreSQL, not namespace-based separation * **Simple API** β€” one call to store a user, one call to retrieve, one call to delete. No policy authoring, no mount configuration, no unseal ceremony * **Audit trail** β€” every API call logged with encrypted PII context, ready for compliance review ## Comparison table | Capability | Databunker Pro | HashiCorp Vault | | --------------------------------------- | ------------------------------------------------------------- | -------------------------------------------------------------- | | **Primary purpose** | PII vault, tokenization & compliance | Infrastructure secrets management | | **Data model** | User profiles (JSON), searchable by email/phone/token | Key-value secrets, no user concept | | **Tokenization** | UUID + format-preserving (credit cards, integers, timestamps) | Transform engine (Enterprise only) | | **Format-preserving tokenization** | Built-in, Luhn-valid credit card tokens | Enterprise license required, limited formats | | **Consent management** | Built-in legal basis & agreement tracking | None | | **DPO portal** | Built-in | None | | **Right to erasure** | Single API call deletes all user data | Manual β€” find and delete each secret path | | **Data subject access requests** | Single API call returns full user profile | No user concept β€” manual aggregation | | **Record versioning** | Built-in version history per user | KV v2 has versioning, but no user-level grouping | | **Audit trail** | Field-level, compliance-ready | API-level, designed for security ops | | **Auto-expiration (data minimization)** | Sliding and absolute TTLs per user record | Secret TTLs, but no user lifecycle management | | **Fuzzy search on encrypted data** | Supported | Not available | | **PII encryption** | AES-256 per-record, FIPS 140-2 compliant | Transit engine encrypts data, but stores ciphertext externally | | **Multi-tenancy** | Native row-level isolation (PostgreSQL) | Namespaces (Enterprise only) | | **Operational complexity** | Docker/Kubernetes deploy, no unseal process | Unseal ceremony, policy authoring, mount configuration | | **DPDP Act / GDPR / HIPAA** | Built-in compliance controls | No privacy-specific compliance features | | **Shamir key sharing** | Master key split for recovery | Unseal keys via Shamir | | **Bulk operations** | Bulk tokenization & export via API | No bulk PII operations | | **Deployment** | Self-hosted, any infrastructure | Self-hosted or HCP Vault (HashiCorp Cloud) | | **License** | Commercial | BSL 1.1 (source-available, not open source) | ## Code examples ### Storing a user profile in Vault (the workaround) Vault has no user profile concept, so teams end up storing PII as KV secrets β€” manually building paths, with no search, no consent tracking, and no way to retrieve "all data for user X" without knowing every path: ```bash theme={null} # Store user PII as a KV secret β€” you manage the path structure vault kv put secret/users/john@example.com \ first="John" \ last="Doe" \ phone="+1-555-123-4567" \ ssn="123-45-6789" \ address="123 Main St" # Retrieve β€” you need to know the exact path vault kv get secret/users/john@example.com # Delete for GDPR erasure β€” hope you tracked every path vault kv delete secret/users/john@example.com # But what about secret/cards/john@example.com? # And secret/consents/john@example.com? # And secret/sessions/john@example.com? ``` No search by phone number. No consent tracking. No audit trail that a DPO can use. No auto-expiration for data minimization. You're building a PII vault from scratch on top of a secrets manager. ### Storing a user profile in Databunker Pro (purpose-built) ```javascript theme={null} const axios = require('axios'); // 1. Store a complete user profile β€” one API call const response = await axios.post('https://your-databunker/v2/UserCreate', { profile: { email: 'john@example.com', first: 'John', last: 'Doe', phone: '+1-555-123-4567', ssn: '123-45-6789', address: '123 Main St' } }, { headers: { 'X-Bunker-Token': process.env.DATABUNKER_API_KEY } }); const userToken = response.data.token; // "a21fa1d3-5e47-11ef-a729-32e05c6f6c16" // 2. Look up by email, phone, or token β€” built-in search const user = await axios.post('https://your-databunker/v2/UserGet', { mode: 'email', identity: 'john@example.com' }, { headers: { 'X-Bunker-Token': process.env.DATABUNKER_API_KEY } }); // 3. GDPR erasure β€” one call deletes everything for this user await axios.post('https://your-databunker/v2/UserDelete', { mode: 'token', identity: userToken }, { headers: { 'X-Bunker-Token': process.env.DATABUNKER_API_KEY } }); ``` Every operation is audited. Consent is tracked. The DPO can see it all in the portal. No path management, no policy authoring, no unseal ceremony. ### Tokenizing credit cards Vault's Transform engine (Enterprise only) can do format-preserving encryption, but it requires configuring roles, transformations, and templates. In Databunker Pro, it's one API call: ```bash theme={null} curl -X POST https://your-databunker/v2/TokenCreate \ -H "X-Bunker-Token: YOUR_API_KEY" \ -d '{ "record": "4532015112830366", "tokentype": "creditcard", "slidingtime": "30d", "unique": true }' ``` ```json theme={null} { "status": "ok", "tokenuuid": "550e8400-e29b-41d4-a716-446655440000", "tokenbase": "4024007186539112" } ``` A Luhn-valid token that passes format validation in downstream systems. Built-in expiration. Built-in deduplication. No Enterprise license required. ## When to use each **Use HashiCorp Vault** for infrastructure secrets: API keys, database credentials, TLS certificates, encryption-as-a-service via the Transit engine. That's what it was built for, and it does it well. **Use Databunker Pro** for personal data: user profiles, credit card numbers, health records, any PII that has regulatory requirements around storage, access, consent, and deletion. They can coexist in the same stack β€” Vault for machine secrets, Databunker Pro for human data. But don't try to make Vault do a PII vault's job. You'll end up building half of Databunker Pro yourself on top of Vault's KV engine, without the compliance features, without the DPO portal, and without the audit trail that regulators actually need. ## The bottom line HashiCorp Vault is a great secrets manager. It's not a PII vault. If you need to store personal data with encryption, tokenization, consent tracking, data subject request handling, and regulatory compliance, you need a tool that was designed for that from the ground up. That's Databunker Pro. # File Vault Source: https://docs.databunker.org/pro/concepts/file-vault Store per-user files encrypted at rest, backed by local disk, Amazon S3, Google Cloud Storage, or Azure Blob Storage β€” with the same key management, multi-tenancy, and access control as the rest of Databunker Pro. Databunker Pro can store files, not just structured records. Each file is attached to a user, encrypted at rest, and served back only through the API. This lets you keep documents such as ID scans, KYC paperwork, medical attachments, or exported reports under the same vault, audit trail, and access-control policies that protect the rest of a user's data. ## How encryption works Every file is encrypted with its own **per-file key**, which is in turn **wrapped by the user's record key**. Nothing is written to storage in the clear, and a file can only be decrypted through the vault. Because the file key is chained to the user's record key, file storage inherits two properties of the PII vault: * **Crypto-shredding on erasure** β€” deleting the user destroys the record key, which renders all of that user's files permanently unrecoverable. This is the mechanism behind GDPR "right to erasure" for attached documents. * **Shared key management** β€” the same key rotation, Shamir's secret sharing, multi-tenancy, and access control apply to files as to any other record. Encrypted objects are stored in a configurable backend: | Backend | Typical use | | -------------------- | ---------------------------------- | | Local disk | Single-node or on-prem deployments | | Amazon S3 | AWS deployments | | Google Cloud Storage | GCP deployments | | Azure Blob Storage | Azure deployments | The storage backend only ever holds ciphertext β€” the keys live in the vault, not with the objects. ## API operations | Endpoint | Purpose | | ------------------- | ----------------------------------- | | `FileCreate` | Store an encrypted file for a user | | `FileGet` | Retrieve and decrypt a file | | `FileListUserFiles` | List a user's files (metadata only) | | `FileDelete` | Remove a file's object and metadata | Every call identifies the owning user with a `mode` (`login`, `token`, `email`, `phone`, or `custom`) and the matching `identity`. ## Store a file File content is supplied as a base64-encoded `filedata` field. The MIME type is auto-detected when `mimetype` is omitted. ```bash theme={null} curl -X POST https://databunker.pro/v2/FileCreate \ -H "X-Bunker-Token: " \ -H "X-Bunker-Tenant: " \ -H "Content-Type: application/json" \ -d '{ "mode": "email", "identity": "user@example.com", "filename": "passport.pdf", "filedata": "JVBERi0xLjQKJ...", "slidingtime": "1y" }' ``` Output: ```json theme={null} { "status": "ok", "token": "550e8400-e29b-41d4-a716-446655440000", "fileuuid": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "duplicate": false } ``` If the same content is uploaded again for the same user, no new object is written and the response sets `"duplicate": true`. ## Retrieve a file Select a file by `fileuuid` (preferred) or by `filename` β€” when selecting by name, the most recently created file with that name is returned. By default the content comes back as a base64-encoded `filedata` field: ```bash theme={null} curl -X POST https://databunker.pro/v2/FileGet \ -H "X-Bunker-Token: " \ -H "X-Bunker-Tenant: " \ -H "Content-Type: application/json" \ -d '{ "mode": "email", "identity": "user@example.com", "fileuuid": "a1b2c3d4-e5f6-7890-abcd-ef1234567890" }' ``` ```json theme={null} { "status": "ok", "fileuuid": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "filename": "passport.pdf", "mimetype": "application/pdf", "size": 20481, "filedata": "JVBERi0xLjQKJ..." } ``` For direct downloads, set `"raw": true` to receive the decrypted bytes with the appropriate `Content-Type` and `Content-Disposition` headers instead of a JSON envelope. ## List a user's files `FileListUserFiles` returns metadata only β€” never file content: ```bash theme={null} curl -X POST https://databunker.pro/v2/FileListUserFiles \ -H "X-Bunker-Token: " \ -H "X-Bunker-Tenant: " \ -H "Content-Type: application/json" \ -d '{ "mode": "email", "identity": "user@example.com" }' ``` ```json theme={null} { "status": "ok", "files": [ { "fileuuid": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "filename": "passport.pdf", "mimetype": "application/pdf", "size": 20481, "creationtime": 1751980800 } ] } ``` ## Delete a file `FileDelete` removes both the stored object and its metadata: ```bash theme={null} curl -X POST https://databunker.pro/v2/FileDelete \ -H "X-Bunker-Token: " \ -H "X-Bunker-Tenant: " \ -H "Content-Type: application/json" \ -d '{ "mode": "email", "identity": "user@example.com", "fileuuid": "a1b2c3d4-e5f6-7890-abcd-ef1234567890" }' ``` ## Retention and expiration Files support the same expiration model as tokens. Set `slidingtime` for a relative retention window (e.g. `30d`, `1y`) or `finaltime` for an absolute cutoff (e.g. `90d`, `2026-01-01`). This lets you enforce document retention policies automatically instead of tracking expiry in your own application. # Fuzzy search Source: https://docs.databunker.org/pro/concepts/fuzzy-search **Fuzzy Search** in Databunker Pro enables intelligent, approximate matching for user records, allowing you to find users even when search terms don't match exactly. This powerful feature is essential for applications that need to handle typos, partial matches, or variations in user data. ## What Problems Does Fuzzy Search Solve? ### 1. **User Experience Enhancement** * βœ… Handles typos and misspellings in search queries * βœ… Enables partial matching for incomplete user data * βœ… Provides intelligent suggestions for user lookup * βœ… Reduces failed searches due to exact-match requirements ### 2. **Data Quality Challenges** * βœ… Works with inconsistent data entry formats * βœ… Handles variations in user-provided information * βœ… Accommodates different naming conventions * βœ… Supports legacy data with formatting inconsistencies ### 3. **Administrative Efficiency** * βœ… Enables quick user discovery in large datasets * βœ… Reduces support tickets from failed user lookups * βœ… Improves admin interface usability * βœ… Supports bulk operations with approximate matching ## How Fuzzy Search Works Databunker Pro's fuzzy search implementation uses advanced algorithms to find users based on similarity rather than exact matches. The system analyzes multiple user attributes and returns results ranked by relevance. ### Supported Search Modes | Search Mode | Description | Use Case | | ----------- | ------------------------- | ------------------------------------ | | `login` | Searches user login names | Finding users by username variations | | `email` | Searches email addresses | Locating users with email typos | | `phone` | Searches phone numbers | Finding users with phone variations | | `custom` | Searches by custom index | Funding users with custom variations | ## API Usage ### Prerequisites Before performing fuzzy searches, you need to: 1. **Create a Bulk List Unlock**: Required for security and audit purposes β€” see the [bulk-unlock UUID reference](/pro/api/authentication#bulk-unlock-uuid) 2. **Obtain proper permissions**: Ensure your token has search capabilities 3. **Prepare search parameters**: Define search mode and criteria ### Basic Fuzzy Search Request ```bash theme={null} curl -X POST "https://your-databunker-instance/v2/UserSearch" \ -H "Content-Type: application/json" \ -H "X-Bunker-Token: YOUR_ACCESS_TOKEN" \ -d '{ "mode": "login", "identity": "user0", "unlockuuid": "your-unlock-uuid" }' ``` ### JavaScript/TypeScript Example (Using Official SDK) ```javascript theme={null} // ES Modules import DatabunkerproAPI from "databunkerpro-js"; // CommonJS // const DatabunkerproAPI = require('databunkerpro-js'); // Initialize the client const client = new DatabunkerproAPI( "https://your-databunker-instance.com", "your-token" ); // Step 1: Create bulk list unlock const unlockResponse = await client.bulkListUnlock(); const unlockUUID = unlockResponse.unlockuuid; // Step 2: Perform fuzzy search const searchResponse = await client.userSearch({ mode: "login", identity: "user0", unlockuuid: unlockUUID, }); // Process results if (searchResponse.status === "ok") { const users = searchResponse.rows; console.log(`Found ${users.length} matching users`); users.forEach((user) => { const profile = user.profile; console.log(`User: ${profile.login} - ${profile.email}`); }); } ``` ### Python Example (Using Official SDK) ```python theme={null} from databunkerpro import DatabunkerproAPI # Initialize the client api = DatabunkerproAPI( base_url="https://your-databunker-instance", x_bunker_token="YOUR_ACCESS_TOKEN", x_bunker_tenant="your-tenant-name" # Optional for multi-tenant setups ) # Step 1: Create bulk list unlock unlock_response = api.bulk_list_unlock() unlock_uuid = unlock_response["unlockuuid"] # Step 2: Perform fuzzy search search_response = api.user_search( mode="login", identity="user0", unlockuuid=unlock_uuid ) if search_response["status"] == "ok": users = search_response["rows"] print(f"Found {len(users)} matching users") for user in users: profile = user["profile"] print(f"User: {profile['login']} - {profile['email']}") ``` ## Real-World Use Cases ### 1. **Customer Support** When customers contact support with partial or misspelled information, fuzzy search helps quickly locate their accounts: ### 2. **User Administration** Administrators can find users even with incomplete information: ### 3. **Data Migration** During system migrations, fuzzy search helps match records with slight variations: ## Security Considerations ### Access Control Fuzzy search respects Databunker Pro's Conditional Role-Based Access Control (CRBAC): * **Policy Enforcement**: Search results are filtered based on user permissions * **Audit Logging**: All search operations are logged for compliance * **Data Minimization**: Only authorized fields are returned in results ### Privacy Protection * **Encrypted Storage**: All user data remains encrypted during search operations * **Secure Transmission**: Search requests use HTTPS encryption * **Access Logging**: Complete audit trail of all search activities ## Error Handling ### Common Error Scenarios ```javascript theme={null} try { const searchResponse = await api.makeRequest("UserSearch", { mode: "login", identity: "nonexistent", unlockuuid: unlockUUID, }); if (searchResponse.status === "error") { console.log("Search failed:", searchResponse.message); } else if (searchResponse.rows.length === 0) { console.log("No matching users found"); } } catch (error) { console.error("Search request failed:", error); } ``` ## Official JavaScript/TypeScript SDK For JavaScript and TypeScript developers, we provide an official SDK that simplifies integration with Databunker Pro's fuzzy search capabilities. ### Installation ```bash theme={null} npm install databunkerpro-js ``` ### SDK Features The [Databunker Pro JavaScript client](https://github.com/securitybunker/databunkerpro-js) provides: * **TypeScript support** with full type definitions * **ES Modules and CommonJS** compatibility * **Comprehensive API coverage** for all Databunker Pro features * **Built-in error handling** and validation * **User Management** (create, read, update, delete) * **Token Management** * **Fuzzy Search capabilities** * **System Operations** ### Advanced JavaScript/TypeScript Example ```typescript theme={null} import DatabunkerproAPI from "databunkerpro-js"; class UserSearchService { private client: DatabunkerproAPI; private unlockUUID?: string; constructor(baseUrl: string, token: string) { this.client = new DatabunkerproAPI(baseUrl, token); } private async ensureUnlock(): Promise { if (!this.unlockUUID) { const response = await this.client.bulkListUnlock(); this.unlockUUID = response.unlockuuid; } return this.unlockUUID; } async searchUsers(mode: string, identity: string) { const unlockUUID = await this.ensureUnlock(); const response = await this.client.userSearch({ mode, identity, unlockuuid: unlockUUID, }); if (response.status !== "ok") { throw new Error(`Search failed: ${response.message || "Unknown error"}`); } return response.rows; } async findUserByEmail(email: string) { return this.searchUsers("email", email); } async findUserByLogin(login: string) { return this.searchUsers("login", login); } async findUserByPhone(phone: string) { return this.searchUsers("phone", phone); } } // Usage example const searchService = new UserSearchService( "https://your-databunker-instance.com", "your-token" ); // Search for users with error handling try { const users = await searchService.findUserByLogin("john"); console.log(`Found ${users.length} matching users`); users.forEach((user) => { const profile = user.profile; console.log(`Found: ${profile.login} - ${profile.email}`); }); } catch (error) { console.error("Search failed:", error.message); } ``` ## Official Python SDK For Python developers, we provide an official SDK that simplifies integration with Databunker Pro's fuzzy search capabilities. ### Installation ```bash theme={null} pip install databunkerpro ``` Or install directly from GitHub: ```bash theme={null} pip install git+https://github.com/securitybunker/databunkerpro-python.git ``` ### SDK Features The [Databunker Pro Python client](https://github.com/securitybunker/databunkerpro-python) provides: * **Type hints and comprehensive documentation** * **Error handling and validation** * **User Management** (create, read, update, delete) * **Token Management** * **Fuzzy Search capabilities** * **System Statistics** ### Advanced Python Example ```python theme={null} from databunkerpro import DatabunkerproAPI from typing import List, Dict, Optional class UserSearchService: def __init__(self, base_url: str, token: str, tenant: Optional[str] = None): self.api = DatabunkerproAPI( base_url=base_url, x_bunker_token=token, x_bunker_tenant=tenant ) self._unlock_uuid: Optional[str] = None def _ensure_unlock(self) -> str: """Ensure we have a valid unlock UUID""" if not self._unlock_uuid: response = self.api.bulk_list_unlock() self._unlock_uuid = response["unlockuuid"] return self._unlock_uuid def search_users(self, mode: str, identity: str) -> List[Dict]: """Search for users using fuzzy matching""" unlock_uuid = self._ensure_unlock() response = self.api.user_search( mode=mode, identity=identity, unlockuuid=unlock_uuid ) if response["status"] == "ok": return response["rows"] else: raise Exception(f"Search failed: {response.get('message', 'Unknown error')}") def find_user_by_email(self, email: str) -> List[Dict]: """Find users by email with fuzzy matching""" return self.search_users("email", email) def find_user_by_login(self, login: str) -> List[Dict]: """Find users by login with fuzzy matching""" return self.search_users("login", login) # Usage example search_service = UserSearchService( base_url="https://your-databunker-instance", token="YOUR_ACCESS_TOKEN", tenant="your-tenant-name" ) # Search for users users = search_service.find_user_by_login("john") for user in users: profile = user["profile"] print(f"Found: {profile['login']} - {profile['email']}") ``` ## Integration Examples The JavaScript/TypeScript examples above can be easily adapted for any frontend framework (React, Vue, Angular) or backend environment (Node.js, Deno, Bun). The core API integration pattern remains the same across all environments. ## Conclusion Databunker Pro's Fuzzy Search API provides a powerful, secure, and efficient way to find users in large datasets. By combining intelligent matching algorithms with robust security controls, it enables applications to deliver excellent user experiences while maintaining data privacy and compliance requirements. The fuzzy search capability is particularly valuable for: * Customer support systems * User administration interfaces * Data migration projects * Applications with large user bases ### Getting Started We provide official SDKs for both JavaScript/TypeScript and Python developers: **For JavaScript/TypeScript developers:** * [Databunker Pro JavaScript SDK](https://github.com/securitybunker/databunkerpro-js) - `npm install databunkerpro-js` * TypeScript support with full type definitions * ES Modules and CommonJS compatibility * Comprehensive API coverage **For Python developers:** * [Databunker Pro Python SDK](https://github.com/securitybunker/databunkerpro-python) - `pip install databunkerpro` * Type hints and comprehensive documentation * Built-in error handling and validation Both SDKs provide: * Simplified API integration * Built-in error handling and validation * Support for all Databunker Pro features including fuzzy search With proper implementation and security considerations, fuzzy search can significantly improve your application's usability and user satisfaction. # Multi-jurisdiction deployment Source: https://docs.databunker.org/pro/concepts/global-deployment For global organisations subject to **data-localisation** obligations in multiple countries, the right architecture is to run **one Databunker Pro instance per jurisdiction**. Each instance keeps the PII for that jurisdiction inside the jurisdiction, with its own keys, audit trail, and operators if local law requires. This page covers the pattern, the reasons behind it, and how the privacy office runs operations across N deployments without violating data-localisation rules. ## The problem this pattern solves A growing number of jurisdictions explicitly prohibit transferring personal data out of the country β€” or impose burdensome conditions that make centralising PII in one cloud region commercially impractical. Examples: | Jurisdiction | Law / framework | Localisation stance | | ------------ | -------------------------- | --------------------------------------------------------------------------------------------------------- | | EU / EEA | GDPR (Chapter V transfers) | Cross-border transfers require an Article 45 adequacy decision, Article 46 safeguards, or SCCs. | | India | DPDPA | Cross-border transfers permitted only to whitelisted countries; sensitive data subject to stricter rules. | | Russia | Federal Law 152-FZ | Personal data of Russian citizens must be **stored and primarily processed** inside Russia. | | Turkey | KVKK | Cross-border transfer requires explicit consent or KVKK Board approval. | | Saudi Arabia | PDPL | Restrictions on cross-border transfer of personal data of residents. | | Brazil | LGPD | Cross-border transfer permitted under specific legal bases, with ANPD oversight. | | China | PIPL | Strict cross-border transfer requirements, including CAC security assessment for large processors. | A single-region deployment that holds PII for all these jurisdictions in, say, AWS Frankfurt, is non-compliant the moment a Russian, Indian, or Chinese resident's record lands in the vault. ## The pattern Deploy a separate Databunker Pro instance in each jurisdiction where you hold PII. Each instance is: * **Independent** β€” its own database, its own master key, its own wrapping key, its own audit log. * **In-region** β€” deployed on local cloud infrastructure (AWS Mumbai, Azure Russia, etc.) or local on-prem hardware. * **Operated locally** if local law requires (operator citizenship, residency, or licensing constraints). The application chooses which regional vault to call based on user domicile, data classification, or originating system. ```text theme={null} [ Application ] | +-------------------+-------------------+-------------------+-------------------+ | | | | | v v v v v [ Pro β€” EU ] [ Pro β€” India ] [ Pro β€” Russia ] [ Pro β€” Turkey ] [ Pro β€” Brazil ] GDPR boundary DPDPA boundary 152-FZ boundary KVKK boundary LGPD boundary keys local keys local keys local keys local keys local audit local audit local audit local audit local audit local ``` Each regional vault holds **only** the records of users domiciled in that jurisdiction. Cross-vault correlation is not possible at the SQL or token layer β€” that is the point of the pattern. ## The next-order problem: operating privacy across N vaults Once an organisation has five, ten, or fifteen regional Pro deployments, the privacy office faces a new problem: * A data subject in India submits a DSAR through the company's global website. How does the DPO team find their data without logging into the Indian Pro instance separately? * A consent withdrawal in Brazil needs to propagate to every system that holds the user's data β€” but the regional vaults are intentionally air-gapped at the PII level. * A compliance report for the EU board needs aggregated metrics (number of records, DSAR counts, consent rates) across every region. Running a separate DPO seat per vault is impractical at scale. ## The unifier: Databunker DPO [**Databunker DPO**](https://databunker.org/use-case/dpo-management-portal/) is the operational layer designed for exactly this scenario. DPO connects to each regional Pro deployment over an authenticated channel and gives the privacy office a **single UI** spanning the full estate, with the critical property that: * **Minimises the chance of PII leaving its home jurisdiction.** By design, only **operational signals** flow through DPO β€” DSAR tickets, consent state transitions, audit summaries, processing-activity metadata, aggregated metrics. Raw PII is never required for these operations, so under normal operation it stays inside the regional vault. Customers remain responsible for configuring DPO and any custom workflows to honour their local data-localisation constraints. * Each regional Pro deployment continues to enforce its own access control, audit, and key custody locally. This lets a small privacy team operate at global scale without violating any localisation rule, because the data that crosses borders in the DPO operational plane is not personal data β€” it is metadata about the privacy operations themselves. ### DPO deployment options | Option | When to use | | ------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | **SaaS (default)** | DPO hosted in the Databunker Portal. The privacy team logs in via the web. Best for most customers. | | **Self-hosted** | Enterprise customers who require the operational layer to also run inside their own perimeter (e.g., highly regulated industries, sovereign clouds) can self-host DPO. | ## When NOT to use this pattern This pattern is for organisations operating in **multiple jurisdictions with localisation constraints**. If you operate in a single jurisdiction, or in multiple jurisdictions without conflicting localisation rules, the right tool is [**multi-tenancy inside a single Pro instance**](/pro/administration/multi-tenancy) β€” it gives cryptographic per-domain isolation without the operational overhead of running N deployments. | Use one Pro + multi-tenancy when | Use multi-jurisdiction Pro deployments when | | ------------------------------------------ | -------------------------------------------------------- | | Single jurisdiction. | Multiple jurisdictions with localisation laws. | | Multiple security domains, one legal home. | Each region's PII is legally required to stay in-region. | | One operations team. | Local operations possibly required by law. | The two patterns can be combined: each regional Pro deployment can itself use multi-tenancy internally to separate its security domains (Student Services vs Analytics vs External Integrations), so the architecture remains consistent regardless of scale. ## Related * [Multi-tenancy](/pro/administration/multi-tenancy) β€” per-instance tenant isolation (different concern). * [Architecture](/pro/get-started/architecture) β€” core single-instance architecture. * [Security overview](/pro/get-started/security-overview) β€” sovereignty and key custody guarantees that make this pattern work. * [Databunker DPO](https://databunker.org/use-case/dpo-management-portal/) β€” the operational unifier across regional Pro deployments. # Record versioning Source: https://docs.databunker.org/pro/concepts/record-versioning **Record Versioning** in Databunker Pro provides automatic version history tracking for user profiles and application data. Every time a record is created or updated, Databunker Pro automatically creates a new version, allowing you to track changes over time, audit data modifications, and restore previous states when needed. ## Configuration Record versioning is **not enabled by default**. To enable versioning, you need to configure it in your `databunker.yaml` configuration file: ```yaml theme={null} versioning: enabled: true max_versions: 10 max_version_retention_period: "1m" ``` After enabling versioning in the configuration file, restart your Databunker Pro instance for the changes to take effect. ## What Problems Does Record Versioning Solve? ### 1. **Change History & Data Integrity** * βœ… Complete history of all data changes over time * βœ… Track what changed and when it changed * βœ… Verify data integrity with cryptographic hashes * βœ… Maintain immutable record of data evolution ### 2. **Data Recovery & Rollback** * βœ… Restore previous versions of user data * βœ… Recover from accidental data modifications * βœ… Undo unwanted changes quickly * βœ… Maintain data consistency across systems ### 3. **Change Tracking & Analysis** * βœ… Understand how user data evolves over time * βœ… Analyze patterns in data modifications * βœ… Identify data quality issues * βœ… Support forensic investigations ## How Record Versioning Works Databunker Pro automatically creates a new version every time you: * Create a new user record * Update a user profile * Create application data * Update application data Each version includes: * **Version number**: Sequential integer starting from 1 * **Operation time**: Unix timestamp of when the version was created * **MD5 hash**: Cryptographic hash for integrity verification * **Full record data**: Complete snapshot of the record at that point in time ## Supported Record Types Record versioning is available for: | Record Type | API Endpoints | Use Case | | -------------------- | -------------------------------------------------- | --------------------------------------------------------------- | | **User Profiles** | `UserListVersions`, `UserGet` (with version) | Track user profile changes, email updates, phone number changes | | **Application Data** | `AppdataListVersions`, `AppdataGet` (with version) | Track application-specific data changes, configuration updates | ## User Profile Versioning ### Listing User Versions To see all versions of a user's profile: ```bash theme={null} curl -X POST "https://your-databunker-instance/v2/UserListVersions" \ -H "Content-Type: application/json" \ -H "X-Bunker-Token: YOUR_ACCESS_TOKEN" \ -d '{ "mode": "token", "identity": "user-token-here" }' ``` **Response:** ```json theme={null} { "status": "ok", "versions": [ { "version": 1, "optime": 1699123456, "md5": "a1b2c3d4e5f6..." }, { "version": 2, "optime": 1699123500, "md5": "b2c3d4e5f6a1..." }, { "version": 3, "optime": 1699123600, "md5": "c3d4e5f6a1b2..." } ] } ``` ### Retrieving a Specific User Version To retrieve a specific version of a user's profile: ```bash theme={null} curl -X POST "https://your-databunker-instance/v2/UserGet" \ -H "Content-Type: application/json" \ -H "X-Bunker-Token: YOUR_ACCESS_TOKEN" \ -d '{ "mode": "token", "identity": "user-token-here", "version": 1 }' ``` **Response:** ```json theme={null} { "status": "ok", "token": "user-token-here", "profile": { "login": "versionuser", "email": "versionuser@email.com" }, "version": 1 } ``` ### JavaScript/TypeScript Example ```javascript theme={null} import DatabunkerproAPI from "databunkerpro-js"; const client = new DatabunkerproAPI( "https://your-databunker-instance.com", "your-token" ); // Step 1: Create a user const createResponse = await client.userCreate({ profile: { login: "versionuser", email: "versionuser@email.com" } }); const userToken = createResponse.token; // Step 2: Update the user profile await client.userUpdate({ mode: "token", identity: userToken, profile: { login: "versionuser", email: "versionuser2@email.com" } }); // Step 3: Update again await client.userUpdate({ mode: "token", identity: userToken, profile: { login: "versionuser", email: "versionuser3@email.com" } }); // Step 4: List all versions const versionsResponse = await client.userListVersions({ mode: "token", identity: userToken }); console.log("User versions:", versionsResponse.versions); // Output: [ // { version: 1, optime: 1699123456, md5: "..." }, // { version: 2, optime: 1699123500, md5: "..." }, // { version: 3, optime: 1699123600, md5: "..." } // ] // Step 5: Retrieve a specific version const version1 = await client.userGet({ mode: "token", identity: userToken, version: 1 }); console.log("Version 1 email:", version1.profile.email); // Output: "versionuser@email.com" const version2 = await client.userGet({ mode: "token", identity: userToken, version: 2 }); console.log("Version 2 email:", version2.profile.email); // Output: "versionuser2@email.com" ``` ### Python Example ```python theme={null} from databunkerpro import DatabunkerproAPI api = DatabunkerproAPI( base_url="https://your-databunker-instance", x_bunker_token="YOUR_ACCESS_TOKEN" ) # Step 1: Create a user create_response = api.user_create({ "profile": { "login": "versionuser", "email": "versionuser@email.com" } }) user_token = create_response["token"] # Step 2: Update the user profile api.user_update({ "mode": "token", "identity": user_token, "profile": { "login": "versionuser", "email": "versionuser2@email.com" } }) # Step 3: Update again api.user_update({ "mode": "token", "identity": user_token, "profile": { "login": "versionuser", "email": "versionuser3@email.com" } }) # Step 4: List all versions versions_response = api.user_list_versions({ "mode": "token", "identity": user_token }) print("User versions:", versions_response["versions"]) # Output: [ # {"version": 1, "optime": 1699123456, "md5": "..."}, # {"version": 2, "optime": 1699123500, "md5": "..."}, # {"version": 3, "optime": 1699123600, "md5": "..."} # ] # Step 5: Retrieve a specific version version1 = api.user_get({ "mode": "token", "identity": user_token, "version": 1 }) print("Version 1 email:", version1["profile"]["email"]) # Output: "versionuser@email.com" version2 = api.user_get({ "mode": "token", "identity": user_token, "version": 2 }) print("Version 2 email:", version2["profile"]["email"]) # Output: "versionuser2@email.com" ``` ## Application Data Versioning Application data versioning works similarly to user profile versioning, but tracks changes to application-specific data associated with users. ### Listing Appdata Versions ```bash theme={null} curl -X POST "https://your-databunker-instance/v2/AppdataListVersions" \ -H "Content-Type: application/json" \ -H "X-Bunker-Token: YOUR_ACCESS_TOKEN" \ -d '{ "mode": "token", "identity": "user-token-here", "appname": "mytestapp" }' ``` **Response:** ```json theme={null} { "status": "ok", "versions": [ { "version": 1, "optime": 1699123456, "md5": "a1b2c3d4e5f6..." }, { "version": 2, "optime": 1699123500, "md5": "b2c3d4e5f6a1..." }, { "version": 3, "optime": 1699123600, "md5": "c3d4e5f6a1b2..." } ] } ``` ### Retrieving a Specific Appdata Version ```bash theme={null} curl -X POST "https://your-databunker-instance/v2/AppdataGet" \ -H "Content-Type: application/json" \ -H "X-Bunker-Token: YOUR_ACCESS_TOKEN" \ -d '{ "mode": "token", "identity": "user-token-here", "appname": "mytestapp", "version": 1 }' ``` ### JavaScript/TypeScript Example ```javascript theme={null} import DatabunkerproAPI from "databunkerpro-js"; const client = new DatabunkerproAPI( "https://your-databunker-instance.com", "your-token" ); // Step 1: Create user const userResponse = await client.userCreate({ profile: { login: "appuser0", email: "appuser0@email.com" } }); const userToken = userResponse.token; // Step 2: Create appdata await client.appdataCreate({ appname: "mytestapp", mode: "token", identity: userToken, appdata: { score: 0, note: "init" } }); // Step 3: Update appdata multiple times for (let v = 1; v <= 3; v++) { await client.appdataUpdate({ appname: "mytestapp", mode: "token", identity: userToken, appdata: { score: v, note: `update${v}` } }); } // Step 4: List all appdata versions const versionsResponse = await client.appdataListVersions({ appname: "mytestapp", mode: "token", identity: userToken }); console.log("Appdata versions:", versionsResponse.versions); // Output: [ // { version: 1, optime: 1699123456, md5: "..." }, // { version: 2, optime: 1699123500, md5: "..." }, // { version: 3, optime: 1699123600, md5: "..." }, // { version: 4, optime: 1699123700, md5: "..." } // ] // Step 5: Retrieve a specific version const version1 = await client.appdataGet({ appname: "mytestapp", mode: "token", identity: userToken, version: 1 }); console.log("Version 1 appdata:", version1.appdata); // Output: { score: 0, note: "init" } const version2 = await client.appdataGet({ appname: "mytestapp", mode: "token", identity: userToken, version: 2 }); console.log("Version 2 appdata:", version2.appdata); // Output: { score: 1, note: "update1" } ``` ### Python Example ```python theme={null} from databunkerpro import DatabunkerproAPI api = DatabunkerproAPI( base_url="https://your-databunker-instance", x_bunker_token="YOUR_ACCESS_TOKEN" ) # Step 1: Create user user_response = api.user_create({ "profile": { "login": "appuser0", "email": "appuser0@email.com" } }) user_token = user_response["token"] # Step 2: Create appdata api.appdata_create({ "appname": "mytestapp", "mode": "token", "identity": user_token, "appdata": { "score": 0, "note": "init" } }) # Step 3: Update appdata multiple times for v in range(1, 4): api.appdata_update({ "appname": "mytestapp", "mode": "token", "identity": user_token, "appdata": { "score": v, "note": f"update{v}" } }) # Step 4: List all appdata versions versions_response = api.appdata_list_versions({ "appname": "mytestapp", "mode": "token", "identity": user_token }) print("Appdata versions:", versions_response["versions"]) # Step 5: Retrieve a specific version version1 = api.appdata_get({ "appname": "mytestapp", "mode": "token", "identity": user_token, "version": 1 }) print("Version 1 appdata:", version1["appdata"]) # Output: {"score": 0, "note": "init"} version2 = api.appdata_get({ "appname": "mytestapp", "mode": "token", "identity": user_token, "version": 2 }) print("Version 2 appdata:", version2["appdata"]) # Output: {"score": 1, "note": "update1"} ``` ## Real-World Use Cases ### 1. **Compliance & Audit Requirements** Many regulations require maintaining a complete history of data changes: ```javascript theme={null} // Track all changes to user email for GDPR compliance const versions = await client.userListVersions({ mode: "token", identity: userToken }); // Generate audit report const auditReport = versions.versions.map(v => ({ version: v.version, timestamp: new Date(v.optime * 1000), hash: v.md5 })); ``` ### 2. **Data Recovery** Restore previous versions when data is accidentally modified: ```javascript theme={null} // User's email was accidentally changed // Restore from version 2 const previousVersion = await client.userGet({ mode: "token", identity: userToken, version: 2 }); // Restore the email await client.userUpdate({ mode: "token", identity: userToken, profile: { email: previousVersion.profile.email } }); ``` ### 3. **Change Analysis** Analyze how user data changes over time: ```javascript theme={null} // Get all versions and compare changes const versions = await client.userListVersions({ mode: "token", identity: userToken }); for (const v of versions.versions) { const record = await client.userGet({ mode: "token", identity: userToken, version: v.version }); console.log(`Version ${v.version}:`, { timestamp: new Date(v.optime * 1000), email: record.profile.email }); } ``` ### 4. **Application State Management** Track changes to application-specific data: ```javascript theme={null} // Track score changes in a game application const versions = await client.appdataListVersions({ appname: "gameapp", mode: "token", identity: userToken }); // Find when score reached certain milestones for (const v of versions.versions) { const appdata = await client.appdataGet({ appname: "gameapp", mode: "token", identity: userToken, version: v.version }); if (appdata.appdata.score >= 1000) { console.log(`Score milestone reached at version ${v.version}`); } } ``` ## Security Considerations ### Access Control Record versioning respects Databunker Pro's Conditional Role-Based Access Control (CRBAC): * **Policy Enforcement**: Access to version history is controlled by policies * **Audit Logging**: All version access operations are logged ### Privacy Protection * **Encrypted Storage**: All version data remains encrypted at rest * **Secure Transmission**: Version requests use HTTPS encryption * **Access Logging**: Complete audit trail of all version access activities ## Version Metadata Each version includes important metadata: | Field | Type | Description | | --------- | ------- | ------------------------------------------------------- | | `version` | integer | Sequential version number (starts at 1) | | `optime` | integer | Unix timestamp when the version was created | | `md5` | string | MD5 hash of the version data for integrity verification | ## Conclusion Databunker Pro's Record Versioning feature provides a powerful, secure, and efficient way to track changes to user profiles and application data. By automatically maintaining a complete version history with cryptographic integrity verification, it enables applications to: * Meet compliance and audit requirements * Recover from accidental data modifications * Analyze data changes over time * Maintain data integrity and security The versioning capability is particularly valuable for: * Compliance-driven applications (GDPR, HIPAA, etc.) * Applications requiring audit trails * Systems with frequent data updates * Applications needing data recovery capabilities # Select security Source: https://docs.databunker.org/pro/concepts/select-security ## Secure bulk retrieval challenge The primary security challenge with both SQL and NoSQL databases is the risk of secure bulk retrieval (or record-dumping) queries, such as a "SELECT \*" request. When combined with SQL injection or GraphQL injection vulnerabilities, attackers can exploit these queries to dump entire database in a matter of seconds. A malicious actor can access your sensitive records even if a database encryption solution is implemented. To address this threat, the original version of Databunker Pro was designed to retrieve user records only when specific user details were provided. This approach significantly limited attackers' ability to enumerate users stored in Databunker. Even if an attacker managed to obtain a Databunker Pro access token, they would still need to provide specific details like the user's email, phone number, or UUID to access any information. From a security perspective, this design was robust and highly effective. ## The Usability Dilemma Despite the strong security model, we began losing business. Companies provided feedback that they needed a way to list all users as part of their application's admin interface. Initially, we firmly opposed introducing any API that allowed bulk user retrieval, as it conflicted with our strict security principles. However, this resistance came at a cost. While our security model remained robust, our product's usability suffered, which negatively impacted our business. We realized we needed a solution that could balance these conflicting requirements: maintaining high security while providing admins with essential functionality. ## Iteration 1: Adding Basic Controls for Bulk Access Our initial attempt to balance usability and security introduced a two-step approach: 1. **Configuration Setting:** Admins could enable or disable the ability to dump user records entirely. 2. **POST Request Requirement:** A bulk data dump required a POST request, ensuring the action couldn't be triggered by a simple GET request. This solution addressed some concerns but still left room for improvement. ## Iteration 2: Secure Unlock Mechanism Over time, we developed a more secure solution: 1. **Unlock Request:** A special API unlock request must be submited, specifying whether they want to unlock all users or a specific group of users. 2. **Temporary Token:** The unlock request generates a temporary token with a short expiration window (60 seconds). 3. **Token Validation:** During the token's validity period, user records can only be dumped if the token is included in the API request. **This solution ensured that bulk data access required explicit admin intent, was time-restricted, and could not be abused by malicious actors.** The bulk unlock UUID is designed with strict time constraints for enhanced security: * It expires automatically after 60 seconds * It must be included when retrieving records for any group of users * A new UUID must be requested for subsequent bulk operations ## Iteration 3: Fine-Grained Access Control with Policy Engine Our latest iteration introduces a powerful policy engine that provides granular control over bulk operations and user listing capabilities. This enhancement allows organizations to: 1. **Control Bulk Operations Access:** Define exactly who has the right to perform bulk unlock API requests 2. **Group-Specific Access:** Restrict user listing to specific groups or departments 3. **Field-Level Security:** Control which user fields are visible in bulk operations 4. **Role-Based Controls:** Implement role-based access patterns for different admin types Here's an example policy that demonstrates these capabilities: ```json theme={null} { "policyname": "ManagerAccess", "policy": { "Effect": "Allow", "Principal": { "Role": "manager" }, "Action": ["UserGet", "BulkListGroupUsers"], "Resource": [ "${target_group_members:role/team-member}.profile.name", "${target_group_members:role/team-member}.profile.phone", "${target_group_members:role/team-member}.group" ], "Condition": { "StringEquals": { "${user_group_id}": "${target_group_id}" } } } } ``` This policy demonstrates several key security features: 1. **Limited Actions:** The manager role can only perform specific actions (`UserGet` and `BulkListGroupUsers`) 2. **Field Restrictions:** Access is limited to specific fields (name, phone, group) 3. **Group Isolation:** Managers can only access members of their own group 4. **Automatic Data Masking:** Other sensitive fields are automatically masked By implementing these policies, organizations can: * Allow HR managers to list only their department members * Restrict sensitive field access in bulk operations * Implement hierarchical access patterns * Maintain audit trails of all bulk access operations This policy-based approach provides the flexibility needed for complex organizational structures while maintaining strict security controls. It represents a significant evolution from our previous iterations, offering both the security we're known for and the granular control our customers need. ## Conclusion By evolving our approach from basic controls to a secure unlock mechanism, we successfully balanced security and usability. The unlock-and-token method allowed us to meet customer requirements for admin functionality while maintaining the strong security principles that Databunker Pro is known for. This iterative process highlights how addressing user feedback and evolving product features can strengthen both usability and trust without compromising security. # Shared records Source: https://docs.databunker.org/pro/concepts/shared-records **Shared records** in Databunker Pro let you create a short-lived, UUID-addressable view of a specific user's record, optionally scoped to a subset of fields and tagged with a partner reference. They are the safe way to share a user reference across systems or with an external partner β€” instead of handing out a long-lived token that becomes a correlation key, you hand out a time-limited UUID that resolves to exactly the fields you authorise, and expires on its own. In conversation this pattern is sometimes called **shareable identities**; in the API it is **Shared Records**. ## When to use shared records Use a shared record when: * An external partner or downstream system needs to retrieve some fields from a specific user record, but should not be granted a long-lived token. * A cross-system reference is genuinely needed (e.g., sharing a customer between two business systems for a specific workflow), and you want the reference to expire automatically. * You want to avoid creating a deterministic, long-lived token that could become a correlation key across security domains. For day-to-day intra-tenant lookups, use `UserGet` directly β€” shared records are for the *cross-boundary* or *time-limited* case. ## How they work 1. The caller invokes `SharedRecordCreate`, identifying the user by `email` / `phone` / `login` / `token` / `custom` and specifying which fields to share, an expiration (`finaltime`), and optionally a `partner` tag for the audit trail. 2. Databunker Pro returns a `recorduuid` β€” a fresh UUID that addresses this specific shared view. 3. The caller distributes the `recorduuid` to the consumer (downstream system, partner, etc.). 4. The consumer calls `SharedRecordGet` with the `recorduuid` to retrieve the data, until expiration. 5. After expiration, the `recorduuid` no longer resolves β€” the share ends automatically with no clean-up step required. Every create and every retrieval generates an audit event. ## API: Create a shared record ```bash theme={null} curl -X POST https://your-databunker-instance/v2/SharedRecordCreate \ -H "X-Bunker-Token: YOUR_ACCESS_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "mode": "email", "identity": "john.doe@example.com", "fields": "first,last,email", "partner": "partner-acme-billing", "finaltime": "7d" }' ``` ### Request fields | Field | Required | Description | | ------------------ | -------- | --------------------------------------------------------------------------------------------------------------- | | `mode` | yes | How the user is identified: one of `login`, `token`, `email`, `phone`, `custom`. | | `identity` | yes | The identifier value matching `mode` (e.g., the email address when `mode=email`). | | `fields` | no | Comma-separated list of profile fields to include in the share. Omit to share the full profile. | | `partner` | no | A partner / consumer reference name. Recorded in the audit event for accountability. | | `appname` | no | Application name when sharing app-specific data attached to the user. | | `finaltime` | no | Expiration time for the share (e.g., `30m`, `24h`, `7d`). After expiration the `recorduuid` no longer resolves. | | `request_metadata` | no | Runtime context for CRBAC policy evaluation (see [Access control](/pro/administration/access-control)). | ### Response ```json theme={null} { "status": "ok", "recorduuid": "550e8400-e29b-41d4-a716-446655440000" } ``` ## API: Retrieve a shared record ```bash theme={null} curl -X POST https://your-databunker-instance/v2/SharedRecordGet \ -H "X-Bunker-Token: PARTNER_ACCESS_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "recorduuid": "550e8400-e29b-41d4-a716-446655440000" }' ``` ### Request fields | Field | Required | Description | | ------------------ | -------- | -------------------------------------------- | | `recorduuid` | yes | The UUID returned by `SharedRecordCreate`. | | `request_metadata` | no | Runtime context for CRBAC policy evaluation. | ### Response ```json theme={null} { "status": "ok", "data": { "first": "John", "last": "Doe", "email": "john.doe@example.com" } } ``` Only fields explicitly listed in the `fields` parameter at creation time are returned. The consumer never sees the full record. ## Why shared records, not long-lived tokens? Reusing the same deterministic token across multiple systems and partners turns the token into a universal correlation key β€” if it leaks once, an attacker can correlate everything. Shared records avoid this in three ways: * **Time-limited.** A `finaltime` is mandatory in practice; expired shares cannot be reused. * **Field-limited.** The `fields` parameter is data-minimisation by construction β€” partners receive only what they need. * **Audit-attributable.** The `partner` tag plus the audit trail attribute every retrieval to a named consumer. ## Related * [PII Vault](/pro/get-started/pii-vault) β€” how regular user tokens work. * [Sub-accounts](/pro/concepts/sub-accounts) β€” multi-tenant patterns that limit deterministic-token reuse across security domains. * [Access control](/pro/administration/access-control) β€” CRBAC policies and `request_metadata`. # Sub-accounts Source: https://docs.databunker.org/pro/concepts/sub-accounts **Sub-accounts** (also referred to as **hierarchical accounts**) in Databunker Pro enable organizations to create isolated account structures within their Databunker Pro instance. This feature is essential for businesses that need to manage multiple independent accounts, departments, or organizational units while maintaining data isolation and administrative control. ## What Problems Do Sub-accounts Solve? ### 1. **Organizational Structure Management** * βœ… Create isolated account spaces for different departments or business units * βœ… Maintain separate administrative control for each sub-account * βœ… Enable independent data management per sub-account * βœ… Support hierarchical organizational structures ### 2. **Multi-tenant SaaS Applications** * βœ… Provide isolated data storage for each customer * βœ… Enable customer-specific administrative access * βœ… Maintain complete data separation between accounts * βœ… Support white-label or reseller scenarios ### 3. **Compliance and Data Isolation** * βœ… Ensure complete data isolation between sub-accounts * βœ… Meet regulatory requirements for data separation * βœ… Enable independent audit trails per sub-account * βœ… Support compliance with data residency requirements ## Implementation Approaches Databunker Pro provides two primary approaches for implementing sub-accounts: 1. **Multi-tenancy Support** - Creates isolated tenants with dedicated admin tokens 2. **Groups with Roles and Policies** - Uses Databunker Pro's CRBAC system for group-based management These approaches can also be combined together to create an even more flexible solution that leverages both database-level isolation from multi-tenancy and fine-grained access control from groups. ## Approach 1: Multi-tenancy Support Multi-tenancy is the recommended approach when you need complete data isolation and independent administrative control for each sub-account. After creating a tenant, you receive a tenant admin token that allows full management of all records within that tenant. ### How It Works When you create a new tenant using the multi-tenancy feature: 1. A new isolated tenant is created with its own data namespace 2. A **tenant admin token** is generated that provides full administrative access 3. All records created within this tenant are completely isolated from other tenants at the database level using PostgreSQL's row-level security (RLS). **Note:** Multi-tenancy requires PostgreSQL and is not supported with MySQL. 4. The tenant admin token can manage all user records, application data, and configurations within the tenant Records are separated from one tenant to another at the database level. This separation is implemented using PostgreSQL's row-level security mechanism, which ensures that queries executed by specific tenants are restricted to their own records, providing complete data isolation. ### Creating a Sub-account with Multi-tenancy ```bash theme={null} curl -H 'X-Bunker-Token: ROOT-ACCESS-TOKEN' \ -X POST https://your-databunker-instance/v2/TenantCreate \ -H 'Content-Type: application/json' \ --data '{ "tenantorg": "acme-corp", "tenantname": "subaccount-001" }' ``` **Response:** ```json theme={null} { "status": "ok", "xtoken": "TENANT-ADMIN-TOKEN-001" } ``` ### Using the Tenant Admin Token The tenant admin token is one of several credential types β€” see the [Authentication reference](/pro/api/authentication) for the full hierarchy. Once you have the tenant admin token, you can use it to manage all records within that tenant: ```bash theme={null} # Create a user in the sub-account curl -H 'X-Bunker-Token: TENANT-ADMIN-TOKEN-001' \ -H 'X-Bunker-Tenant: subaccount-001' \ -H 'Content-Type: application/json' \ -X POST https://your-databunker-instance/v2/UserCreate \ --data '{ "profile": { "login": "user1", "email": "user1@subaccount-001.com", "firstname": "John", "lastname": "Doe" } }' ``` ### JavaScript/TypeScript Example ```javascript theme={null} import DatabunkerproAPI from "databunkerpro-js"; // Initialize root admin client const rootClient = new DatabunkerproAPI( "https://your-databunker-instance.com", "ROOT-ACCESS-TOKEN" ); // Step 1: Create a new sub-account (tenant) const tenantResponse = await rootClient.tenantCreate({ tenantorg: "acme-corp", tenantname: "subaccount-001" }); const tenantAdminToken = tenantResponse.xtoken; const tenantName = "subaccount-001"; // Step 2: Initialize client with tenant admin token const tenantClient = new DatabunkerproAPI( "https://your-databunker-instance.com", tenantAdminToken ); // Step 3: Create users in the sub-account const userResponse = await tenantClient.userCreate({ profile: { login: "user1", email: "user1@subaccount-001.com", firstname: "John", lastname: "Doe" } }); console.log("Sub-account created with tenant admin token:", tenantAdminToken); console.log("User created in sub-account:", userResponse.token); ``` ### Python Example ```python theme={null} from databunkerpro import DatabunkerproAPI # Initialize root admin client root_api = DatabunkerproAPI( base_url="https://your-databunker-instance", x_bunker_token="ROOT-ACCESS-TOKEN" ) # Step 1: Create a new sub-account (tenant) tenant_response = root_api.tenant_create({ "tenantorg": "acme-corp", "tenantname": "subaccount-001" }) tenant_admin_token = tenant_response["xtoken"] tenant_name = "subaccount-001" # Step 2: Initialize client with tenant admin token tenant_api = DatabunkerproAPI( base_url="https://your-databunker-instance", x_bunker_token=tenant_admin_token, x_bunker_tenant=tenant_name ) # Step 3: Create users in the sub-account user_response = tenant_api.user_create({ "profile": { "login": "user1", "email": "user1@subaccount-001.com", "firstname": "John", "lastname": "Doe" } }) print(f"Sub-account created with tenant admin token: {tenant_admin_token}") print(f"User created in sub-account: {user_response['token']}") ``` ### Benefits of Multi-tenancy Approach * **Complete Data Isolation**: Each tenant has its own isolated data namespace * **Independent Administration**: Tenant admin tokens provide full control within the tenant * **Scalability**: Supports unlimited tenants with PostgreSQL row-level security (requires PostgreSQL, not available with MySQL) * **Security**: Built-in tenant separation at the database level * **Compliance**: Meets data residency and isolation requirements ## Approach 2: Groups with Roles and Policies The groups approach leverages Databunker Pro's Conditional Role-Based Access Control (CRBAC) system. Each group can store sub-accounts, and a group admin user manages all users within that group. This approach is implemented using roles and policies. ### How It Works With the groups approach: 1. Create a group to represent the sub-account 2. Assign a **group admin** role to a user who will manage the sub-account 3. Create policies that grant the group admin access to manage users within the group 4. Add users to the group as needed 5. The group admin can manage all users within their assigned group ### Creating a Sub-account with Groups ```bash theme={null} # Step 1: Create a group admin user curl -H 'X-Bunker-Token: YOUR-ACCESS-TOKEN' \ -H 'Content-Type: application/json' \ -X POST https://your-databunker-instance/v2/UserCreate \ --data '{ "profile": { "login": "group-admin-001", "email": "admin@subaccount-001.com", "firstname": "Admin", "lastname": "User" } }' # Step 2: Create a group for the sub-account curl -H 'X-Bunker-Token: YOUR-ACCESS-TOKEN' \ -H 'Content-Type: application/json' \ -X POST https://your-databunker-instance/v2/GroupCreate \ --data '{ "groupname": "subaccount-001", "description": "Sub-account group 001" }' # Step 3: Add the group admin to the group with admin role curl -H 'X-Bunker-Token: YOUR-ACCESS-TOKEN' \ -H 'Content-Type: application/json' \ -X POST https://your-databunker-instance/v2/GroupAddUser \ --data '{ "groupname": "subaccount-001", "mode": "token", "identity": "USER-TOKEN-FROM-STEP-1", "role": "group-admin" }' ``` ### Creating Policies for Group Admin Create a policy that allows the group admin to manage all users within their group: ```bash theme={null} curl -H 'X-Bunker-Token: YOUR-ACCESS-TOKEN' \ -H 'Content-Type: application/json' \ -X POST https://your-databunker-instance/v2/PolicyCreate \ --data '{ "policyname": "subaccount-admin-policy", "policy": { "Effect": "Allow", "Principal": { "Role": "group-admin" }, "Action": [ "UserGet", "UserCreate", "UserUpdate", "UserDelete", "BulkListGroupUsers", "BulkListUnlock", "GroupListUserGroups" ], "Resource": [ "${target_group_members}.profile", "${target_group_members}.consent", "${target_group_members}.appdata" ], "Condition": { "StringEquals": { "${principal_group_id}": "${target_group_id}" } } } }' ``` ### JavaScript/TypeScript Example ```javascript theme={null} import DatabunkerproAPI from "databunkerpro-js"; const client = new DatabunkerproAPI( "https://your-databunker-instance.com", "YOUR-ACCESS-TOKEN" ); // Step 1: Create a group admin user const adminResponse = await client.userCreate({ profile: { login: "group-admin-001", email: "admin@subaccount-001.com", firstname: "Admin", lastname: "User" } }); const adminToken = adminResponse.token; // Step 2: Create a group for the sub-account await client.groupCreate({ groupname: "subaccount-001", description: "Sub-account group 001" }); // Step 3: Add the group admin to the group with admin role await client.groupAddUser({ groupname: "subaccount-001", mode: "token", identity: adminToken, role: "group-admin" }); // Step 4: Create policy for group admin await client.policyCreate({ policyname: "subaccount-admin-policy", policy: { Effect: "Allow", Principal: { Role: "group-admin" }, Action: [ "UserGet", "UserCreate", "UserUpdate", "UserDelete", "BulkListGroupUsers", "BulkListUnlock", "GroupListUserGroups" ], Resource: [ "${target_group_members}.profile", "${target_group_members}.consent", "${target_group_members}.appdata" ], Condition: { StringEquals: { "${principal_group_id}": "${target_group_id}" } } } }); // Step 5: Group admin can now create users in their group const groupAdminClient = new DatabunkerproAPI( "https://your-databunker-instance.com", adminToken ); // Create a user in the sub-account const userResponse = await groupAdminClient.userCreate({ profile: { login: "user1", email: "user1@subaccount-001.com", firstname: "John", lastname: "Doe" } }); // Add user to the group await groupAdminClient.groupAddUser({ groupname: "subaccount-001", mode: "token", identity: userResponse.token, role: "member" }); console.log("Sub-account created using groups approach"); console.log("Group admin token:", adminToken); ``` ### Benefits of Groups Approach * **Flexible Access Control**: Fine-grained permissions using CRBAC policies * **Role-Based Management**: Different roles can be assigned within groups * **Conditional Access**: Policies can include complex conditions for access control * **Compliance Support**: Supports FERPA, GDPR, and DPDPA compliance scenarios * **Hierarchical Structures**: Supports parent-child relationships within groups ## Choosing the Right Approach ### Use Multi-tenancy When: * You need **complete data isolation** between sub-accounts * Each sub-account requires **independent administrative control** * You're building a **multi-tenant SaaS application** * You need to meet **strict data residency requirements** * You want **database-level isolation** for security (requires PostgreSQL, not available with MySQL) ### Use Groups Approach When: * You need **flexible, role-based access control** within sub-accounts * You want to implement **hierarchical organizational structures** * You need **conditional access policies** (e.g., parent-child relationships) * You're building **compliance-focused applications** (FERPA, GDPR, DPDPA) * You want **fine-grained permissions** for different user roles ## Real-World Use Cases ### 1. **SaaS Multi-tenant Application** Create isolated sub-accounts for each customer: ```javascript theme={null} // Create a tenant for each customer const customerTenant = await rootClient.tenantCreate({ tenantorg: "saas-provider", tenantname: `customer-${customerId}` }); // Provide customer with their tenant admin token // Customer can now manage their own data independently ``` ### 2. **Departmental Sub-accounts** Organize departments within an organization: ```javascript theme={null} // Create a group for each department await client.groupCreate({ groupname: "engineering-department", description: "Engineering team sub-account" }); // Assign department admin await client.groupAddUser({ groupname: "engineering-department", mode: "token", identity: deptAdminToken, role: "group-admin" }); ``` ### 3. **Reseller/Partner Program** Enable partners to manage their own customer data: ```javascript theme={null} // Create tenant for each reseller const resellerTenant = await rootClient.tenantCreate({ tenantorg: "partner-program", tenantname: `reseller-${resellerId}` }); // Reseller gets tenant admin token to manage their customers ``` ## Security Considerations ### Multi-tenancy Security * **Row-Level Security**: PostgreSQL RLS ensures tenant data isolation (requires PostgreSQL, not available with MySQL) * **Token-Based Access**: Tenant admin tokens are scoped to their tenant * **Audit Logging**: All tenant operations are logged separately * **Encryption**: Each tenant's data is encrypted independently ### Groups Security * **Policy Enforcement**: CRBAC policies control all access * **Role Validation**: Roles are verified before granting access * **Condition Checks**: Policies include conditions for additional security * **Audit Trail**: All group operations are logged with role information ## Best Practices 1. **Token Management**: Securely store and rotate tenant admin tokens 2. **Policy Design**: Design policies carefully to ensure proper access control 3. **Regular Audits**: Review sub-account access and permissions regularly 4. **Monitoring**: Monitor sub-account activity for security and compliance 5. **Documentation**: Document which approach is used for each sub-account ## Conclusion Databunker Pro provides two powerful approaches for implementing sub-accounts: * **Multi-tenancy** offers complete isolation and independent administration * **Groups with CRBAC** provides flexible, role-based access control Both approaches enable organizations to create secure, scalable sub-account structures that meet their specific requirements for data isolation, administrative control, and compliance. **The approaches can be combined together** to create an even more flexible solution that leverages database-level isolation from multi-tenancy and fine-grained access control from groups. Choose the approach that best fits your use case: * Use **multi-tenancy** for complete isolation and independent administration * Use **groups** for flexible role-based access control and hierarchical structures * **Combine both approaches** for maximum flexibility with database-level isolation and fine-grained permissions # Format-preserving tokenization Source: https://docs.databunker.org/pro/concepts/tokenization Databunker Pro provides **two distinct tokenization engines**, each designed for a different job: * **PII tokenization** (`UserCreate` / `UserGet`) β€” stores a complete user profile (JSON, N fields) as one encrypted record and returns a single UUID token representing the whole profile. Builds secure hashed search indexes over `email`, `phone`, `login`, and a `custom` field for efficient lookups. This is the *user-table replacement* pattern; see the [PII Vault](/pro/get-started/pii-vault) page for full detail. * **Format-preserving tokenization** (`TokenCreate` / `TokenGet`) β€” tokenizes individual sensitive values such as `credit-card numbers` (Luhn-valid) and Unix timestamps. Returns both a UUID and a format-preserving token in the same response. This is the *PCI / single-value* pattern, covered in the rest of this page. Both engines share the same vault, encryption, multi-tenancy, and access-control layers β€” so the same auditability, key management, and CRBAC policies apply to either flow. Databunker Pro was built with the latest data privacy requirements in mind, such as data minimization, and is engineered to handle millions of data tokenization requests. The API supports bulk tokenization for efficient batch operations. ## Supported data types | Original Record Type | Format Preservation | Generated Token Format | | --------------------- | ------------------- | ------------------------------- | | Credit Card Number | βœ… (with Luhn check) | Format-preserving or UUID token | | Unix timestamp record | βœ… | Format-preserving or UUID token | | Text string | ❌ | UUID token | ## Key features ### Automatic Expiration In Databunker Pro, expiration allows you to set a lifespan for sensitive data tokens, ensuring they automatically expire after a defined period. Use `slidingtime` for a relative window (e.g. `30d`, `1h`) or `finaltime` for an absolute Unix-timestamp expiry. ```json theme={null} // Set a 30-day sliding expiration for a tokenized record { "tokentype": "creditcard", "record": "4532015112830366", "slidingtime": "30d" } ``` ### Unique Record Support This unique flag is used for data deduplication. It ensures that each record is saved only once, and the same token value is returned for identical records. If the original record has an expiration flag set, its expiration countdown will be reset from the beginning. ```json theme={null} // Same input generates same token when enabled { "tokentype": "creditcard", "record": "4532015112830366", "unique": true } ``` ### Dual Token Generation By default, Databunker Pro generates two tokens: one in UUID format and another in a format-preserving manner. ```json theme={null} // Example response for credit card tokenization { "status": "ok", "tokenuuid": "550e8400-e29b-41d4-a716-446655440000", "tokenbase": "4111111111111111" // Format-preserving token (Luhn-valid, same length) } ``` ## Getting started ```bash theme={null} # Example API call for tokenization curl -X POST https://databunker.pro/v2/TokenCreate \ -H "X-Bunker-Token: " \ -H "X-Bunker-Tenant: " \ -H "Content-Type: application/json" \ -d '{ "tokentype": "creditcard", "record": "4532015112830366", "slidingtime": "30d", "unique": true }' ``` Output: ```json theme={null} { "status": "ok", "tokenuuid": "550e8400-e29b-41d4-a716-446655440000", "tokenbase": "4111111111111111" // Format-preserving token (Luhn-valid, same length) } ``` ## Bulk tokenization For batch workloads β€” migrations, nightly imports, mass detokenization β€” Databunker Pro creates, reads, and deletes many tokens in a single call. ### Create tokens in bulk `TokenCreateBulk` takes an array of records and returns a token pair for each. `slidingtime` / `finaltime` and `unique` apply to the whole batch. ```bash theme={null} curl -X POST https://databunker.pro/v2/TokenCreateBulk \ -H "X-Bunker-Token: " \ -H "X-Bunker-Tenant: " \ -H "Content-Type: application/json" \ -d '{ "records": [ { "tokentype": "creditcard", "record": "4532015112830366" }, { "tokentype": "creditcard", "record": "5467047429390590" } ], "unique": true }' ``` Output: ```json theme={null} { "status": "ok", "created": [ { "tokenuuid": "550e8400-e29b-41d4-a716-446655440000", "tokenbase": "4111111111111111", "record": "4532015112830366", "tokentype": "creditcard" }, { "tokenuuid": "6ba7b810-9dad-11d1-80b4-00c04fd430c8", "tokenbase": "5500005555555559", "record": "5467047429390590", "tokentype": "creditcard" } ] } ``` ### Read and delete in bulk Bulk read and delete return or destroy plaintext for many records at once, so they require a short-lived **[unlock UUID](/pro/api/authentication#bulk-unlock-uuid)** as an extra authorization step. Call `BulkListUnlock` first, then pass the returned `unlockuuid` to `BulkListTokens` or `BulkDeleteTokens` along with the token UUIDs. ```bash theme={null} # 1. Obtain an unlock UUID curl -X POST https://databunker.pro/v2/BulkListUnlock \ -H "X-Bunker-Token: " \ -H "X-Bunker-Tenant: " # -> { "status": "ok", "unlockuuid": "e1f2a3b4-..." } # 2. Retrieve the original values curl -X POST https://databunker.pro/v2/BulkListTokens \ -H "X-Bunker-Token: " \ -H "X-Bunker-Tenant: " \ -H "Content-Type: application/json" \ -d '{ "unlockuuid": "e1f2a3b4-...", "tokens": ["550e8400-e29b-41d4-a716-446655440000", "6ba7b810-9dad-11d1-80b4-00c04fd430c8"] }' # -> { "status": "ok", "rows": [ { "tokenuuid": "...", "tokenbase": "...", "record": "...", "tokentype": "creditcard" }, ... ] } # 3. Delete tokens curl -X POST https://databunker.pro/v2/BulkDeleteTokens \ -H "X-Bunker-Token: " \ -H "X-Bunker-Tenant: " \ -H "Content-Type: application/json" \ -d '{ "unlockuuid": "e1f2a3b4-...", "tokens": ["550e8400-e29b-41d4-a716-446655440000", "6ba7b810-9dad-11d1-80b4-00c04fd430c8"] }' # -> { "status": "ok", "deleted": 2 } ``` ## Compliance and scale Format-preserving tokenization addresses three concerns at once: | Concern | What tokenization gives you | | ------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | **Privacy & compliance** | Supports GDPR data minimization and reduces PCI DSS scope β€” real card numbers never reach your application databases, logs, or analytics systems. | | **Legacy compatibility** | Tokens keep the original format and validation rules (e.g. the Luhn check for cards), so they drop into existing schemas, validators, and downstream systems without changes. | | **Scale** | Data partitioning and bulk endpoints handle millions of records at high throughput. | # Developer tools Source: https://docs.databunker.org/pro/developer-tools/overview ## SDKs # Architecture Source: https://docs.databunker.org/pro/get-started/architecture In today’s digital landscape, protecting sensitive customer data isn’t just about complianceβ€”it’s about building trust. Databunker Pro offers a next-generation secure vault for personal data (PII/PHI/KYC), combining robust encryption, tokenization, and privacy management in an enterprise-ready platform. ## Core architecture overview **Backend storage** * **PostgreSQL**: Reliable, secure backend for encrypted data storage, with row-level security for true multi-tenant isolation. * **MySQL**: Secure backend for encrypted data storage. Note: Multi-tenancy is not supported with MySQL. * **Redis**: Used for encrypted storage of session information for faster, secure access. **Encryption and key management** * **Two-layer encryption**: Master encryption key secured by a separate wrapping key. * **Wrapping key rotation**: Rotate without re-encrypting all stored data. * **Shamir’s Secret Sharing**: Backup the wrapping key securely across multiple trusted parties. **Privacy management** * **DPO portal** for oversight and reporting. * **Consent management**, **audit trails**, and **data minimization** features built-in. * **One-click personal data reports** and full processing activity logs for compliance. **Scalability and deployment** * **Stateless architecture** for easy horizontal scaling on Kubernetes. * **High availability** with multi-instance deployment and database failover readiness. * **Container-based deployment**: Docker, Docker Compose, and Kubernetes templates included. * **Multi-jurisdiction deployment** β€” for global organisations subject to data-localisation laws in multiple countries, the recommended pattern is to run one Databunker Pro instance per jurisdiction, unified for operations via [Databunker DPO](https://databunker.org/use-case/dpo-management-portal/). See [Multi-jurisdiction deployment](/pro/concepts/global-deployment). **Integration** * Available client libraries for **PHP**, **JavaScript/TypeScript**, **Java**, and **Python** to simplify integration. * For SaaS and database connectors used in data-subject-rights and DPO workflows (Salesforce, HubSpot, MailChimp, MySQL, PostgreSQL, Oracle, SQL Server), see the separate **Databunker DPO** product in the Databunker Portal. Architecture diagram ## Security architecture deep dive **Data protection** * **SSL/TLS encryption** for all API and database communication. * **AES-256 encryption** at rest for all personal data. * **Secure hash-based indexing** for searchable fields like email, phone number, and login names. * **Zero clear-text storage** of sensitive information. **Access control** * Fine-grained, token-based API authentication. * Multi-tenant separation using PostgreSQL Row-Level Security (RLS). Note: Multi-tenancy requires PostgreSQL and is not supported with MySQL. * Default prevention of bulk data extraction. **Threat protection** * SQL injection prevention, API rate limiting, and session hardening. **Key management** * Wrapping key rotation and Shamir’s Secret Sharing-based key backups. *** # Specialized data protection features ## PII / PHI / KYC Data Tokenization / User Table Replacement Databunker Pro enables secure tokenization for full personal profiles (PII/PHI/KYC): * Accepts complete user profile JSON objects and generates a single token representing the full profile. * Builds secure hash-based search indexes automatically for searchable fields (e.g., email, phone number, login names), allowing efficient, privacy-preserving lookups. * Dynamic token expiration options, supporting both sliding and final expiration modes. * Tokens can be safely stored and used across internal systems without revealing sensitive information. ## Credit card tokenization For sensitive payment data, Databunker Pro offers dedicated credit card tokenization capabilities: * Each credit card is tokenized into a secure, unique identifier. * Supports **unique token generation** (same card β†’ same token if enabled). * Dynamic token expiration options, supporting both sliding and final expiration modes * **Bulk tokenization support**: tokenize multiple credit cards efficiently in a single API request, with per-record expiration and validation. *** ## Real-world applications Organizations across industries use Databunker Pro to protect critical personal data: * **Financial Services**: Safeguarding customer PII while maintaining regulatory compliance. * **Healthcare Providers**: Protecting PHI with HIPAA-aligned security controls. * **E-commerce Platforms**: Managing customer data with GDPR compliance and strong privacy controls. * **SaaS Providers**: Implementing true multi-tenant security for user data. *** ## Why Choose Databunker Pro? Databunker Pro is more than just encryption β€” it’s a **privacy-by-design** foundation for modern organizations. With its advanced encryption model, built-in privacy controls, scalable architecture, and rich integration ecosystem, Databunker Pro empowers you to protect sensitive data, comply with regulations, and earn customer trust. # Frequently asked questions Source: https://docs.databunker.org/pro/get-started/faq ### How does Databunker Pro manage sensitive data tokenization? * Tokenizes entire user records (e.g., PII, PHI, KYC, PCI data) using UUID tokens or format-preserving tokens for specific data records (e.g., credit cards). * Encrypts data with AES-256 and stores it in a secure vault. * Provides access via RESTful APIs with role-based access controls (RBAC). * Supports multi-tenancy for secure management of multiple clients. ### How is tokenization handled for multi-cloud or hybrid environments? * Supports multi-cloud and hybrid deployments via Docker Compose, Helm charts, or a cloud-hosted version. * Uses a stateless architecture for consistency across environments with a centralized secure vault for token mapping. * Enables multi-tenancy for secure data separation in shared cloud or hybrid setups. * Offers APIs for seamless integration with cloud-native or on-premises systems. ### Does Databunker Pro implement tokenization for PII, card data, or account information? What approach is used? * Supports PII, card data (PCI), and account information (KYC). * Tokenizes entire records with UUIDs or uses format-preserving tokenization for specific records (e.g., credit card numbers). * Maintains data usability while ensuring security. ### Is there a secure vault for storing token-to-data mappings, or is a deterministic, format-preserving method used without a vault? * Uses a secure vault to store AES-256-encrypted token-to-data mappings. * Offers format-preserving tokenization for specific records (for example for credit cards). * Ensures secure storage and retrieval with isolated vaults for different clients via multi-tenancy. ### Are encryption, secure APIs, and access controls in place during tokenization workflows? * Encrypts data with AES-256 encryption. * Uses secure RESTful APIs with RBAC to handle tokenization. * Supports mutual TLS and certificate pinning for legitimate API access. * Requires time-based tokens for special handling of bulk requests. * Defines retrievable fields with a masking policy, masking others. ### What are the authentication, encryption, and access control mechanisms for the token vault? * **Authentication**: Uses temporary UUID-based access tokens (more secure than JWT, as user identity like email/ID isn’t encoded). Supports passwordless options (e.g., one-time codes via email/SMS) for the optional user portal. * **Encryption**: Employs AES-256 for data and vault storage with secure indexing for searches. * **Access Controls**: Restricts vault access with RBAC and a masking policy defining retrievable fields (others masked). Tracks operations with audit trails. Ensures secure data isolation for different clients via multi-tenancy. ### Does the tokenization process align with regulations like RBI, PCI DSS, GDPR, etc.? * Engineered to operate inside compliance programmes including **RBI, DPDPA, PCI DSS, GDPR, HIPAA, FERPA, ISO 27001, and SOC 2**. Databunker Pro provides the technical controls (AES-256 encryption, hashed indexing, CRBAC, audit trail, tenant isolation, key management) these frameworks require. * Databunker Pro has historically been self-hosted, so customers typically inherit cloud-provider certifications (AWS, Azure, GCP) and add their own organisational SOC 2 / ISO 27001 on top. * Product-level **SOC 2** attestation is in progress for the managed cloud offering (Databunker Portal) β€” expected within \~2–3 months. **ISO 27001** product-level certification is roadmapped alongside SOC 2. * Supports data minimization, user consent management, audit trails, and a User Privacy Portal for data subject rights. * Meets RBI's data localization and GDPR's privacy requirements via self-hosted in-region deployment. * Provides multi-tenancy for compliance in multi-client environments. ### What about IRAP for Australian deployments? * Databunker Pro is not currently IRAP-assessed at the product level. * Because Databunker Pro is self-hosted inside your own cloud tenant, it inherits the IRAP boundary of the underlying platform β€” **AWS Sydney (`ap-southeast-2`) and Azure Australia East are IRAP-assessed at PROTECTED**, and Databunker Pro runs cleanly inside that boundary. * A product-level IRAP assessment can be scoped under professional services if your contract requires it. Australian public-sector and university customers typically combine the cloud platform's IRAP assessment with their own organisational IRAP scope and treat Databunker Pro as a controlled component inside it. ### What is the de-tokenization policy? Is it role-based, audited, and strictly controlled? * Role-based de-tokenization requiring RBAC permissions. * Defines retrievable fields with a masking policy, masking others. * Audits all operations with strict controls for compliance. * Ensures tenant-specific de-tokenization via multi-tenancy. ### What audit and monitoring capabilities are provided for tokenization activities? * Provides comprehensive audit trails, logging all tokenization and de-tokenization activities (user, timestamp, data accessed, data before and after change). * Currently offers no special monitoring capabilities beyond audit logs. * Segregates audit logs per client via multi-tenancy. ### How is high availability and disaster recovery ensured for the tokenization engine? * Ensures high availability as a stateless service through containerized deployments (Docker, Helm) with load balancing. * Supports disaster recovery via database backups (PostgreSQL/MySQL) and replication. ### Is the tokenization system scalable to support large transaction volumes (e.g., millions of transactions per day)? What are the performance benchmarks? Yes. Databunker Pro is built in Go on a stateless, horizontally-scalable architecture. A recent internal benchmark β€” a single Databunker Pro instance on AWS EC2 `m6i.2xlarge` backed by a **dedicated AWS RDS PostgreSQL** database (10,000,000 records, 120-field user profiles) β€” sustained **\~5,800 records/sec** on bulk writes with linear scaling, ingesting 10 M records in \~28 minutes. Detokenisation (`UserGet`) ran at \~14 ms p50. Throughput **scales by adding stateless Databunker Pro instances** against the same database. At small table sizes this is near-linear (a short 6-instance test reached \~34,400 records/sec); at large row counts the **database CPU** becomes the limit (a sustained 50 M, 4-instance run drove RDS to \~80% CPU at \~11,800 records/sec), so size up the database as you grow. See the [performance page](/pro/get-started/performance) for the full sizing guide. For the full benchmark methodology, latency / throughput / storage numbers, and capacity-planning guidance, see [Performance & benchmarks](/pro/get-started/performance). ### How is token uniqueness ensured? Do you use randomization, hashing with salt, or cryptographic mapping? * Ensures token uniqueness by checking for duplicate records in the database and regenerating UUID tokens if duplicates are found. * Uses cryptographic mapping for format-preserving tokens with hash-based indexing and salts for deduplication. * Maintains unique tokens per tenant via multi-tenancy. ### What cryptographic algorithms are used in token generation? Are they NIST-compliant? * Uses AES-256 for encryption, SHA-256 for secure indexing, and cryptographic UUIDs or format-preserving methods for token generation. * Aligns with NIST standards for encryption and key management. * Supports secure multi-tenant environments. ### How are keys managed in the tokenization process? Are they stored in an HSM? What is the key rotation and lifecycle management policy? * Manages keys securely with a **master key** (never exposed) encrypting sensitive data in the vault using AES-256. * Protects the master key with a **wrapping key**, storable as a Kubernetes secret or retrievable from AWS Key Vault, HashiCorp Vault, or HSMs (requires custom development). * Supports **Shamir’s Secret Sharing** for generating wrapping keys, requiring 3 out of 5 key shares to reconstruct. * Configures key rotation following best practices for lifecycle management. ### What mechanisms prevent token mapping leakage or reverse engineering of the token? Is there protection against brute-force or pattern analysis? * Prevents leakage and reverse engineering by using tokens (UUID-based or format-preserving) as pointers to AES-256-encrypted data in a secure vault. * Ensures tokens contain no inherent data, making reverse engineering infeasible without vault access. * Protects against brute-force or pattern analysis with RBAC, audit logs, and optional mutual TLS. * Prevents cross-tenant leakage via multi-tenancy. ### How does Databunker Pro handle tokenization for structured and unstructured data? Is it applicable to database fields, documents, or images (e.g., OCR data)? * Tokenizes structured data (e.g., database fields like PII, or credit cards in PCI). * For unstructured data (e.g., documents, OCR-extracted data), recommends generating a random password, saving it in the user profile, and using it to encrypt the original file. ### What happens if underlying data is updated after a token is generated and sent to the cloud? Is a new token generated, or is the old token updated? * Maintains the existing token’s validity, mapping to the updated data in the vault. * Generates no new token unless a new record is created (checked via deduplication). * Audits and encrypts updates, ensuring tenant-specific updates via multi-tenancy. * Record versioning is supported as an optional mode (see [Record Versioning](/pro/concepts/record-versioning)). When enabled, every create and update retains an immutable version of the record with integrity checks, supporting forensic review, compliance audits, and rollback. # Databunker Pro Source: https://docs.databunker.org/pro/get-started/overview Databunker Pro is a self-hosted secure vault and a safer alternative to traditional user tables in SQL and NoSQL databases. It encrypts sensitive data (PII, PHI, PCI, KYC) and replaces it in your database with safe, random tokens β€” without slowing down your app’s performance. That way, if someone breaches your system, they can’t get the real data, and you stay compliant with GDPR, CCPA, HIPAA, etc., using a simple API. Some of Databunker Pro's enterprise security features: * [Fuzzy search](/pro/concepts/fuzzy-search) * [Multi-tenancy](/pro/administration/multi-tenancy) * [Key rotation](/pro/administration/key-rotation) * [File Vault](/pro/concepts/file-vault) * [Record versioning](/pro/concepts/record-versioning) * [Shamir's secret sharing](/pro/administration/shamir-keys) * [Advanced access control](/pro/administration/access-control) * [Format-preserving tokenization](/pro/concepts/tokenization) * [Multi-jurisdiction deployment](/pro/concepts/global-deployment) ## Compare Databunker Pro with popular tools ## Try it out for yourself Explore common use cases in our sandbox. # Performance & benchmarks Source: https://docs.databunker.org/pro/get-started/performance Measured Databunker Pro throughput, detokenisation latency, and storage at 10M, 50M, and 100M records on dedicated AWS RDS PostgreSQL β€” with a sizing guide for choosing database and application instances by record count. This page gives architects the numbers needed to size a Databunker Pro deployment. Every figure below is **measured** β€” we loaded a 120-field user-profile vault to **10, 50, and 100 million records** against a **dedicated AWS RDS PostgreSQL** database and recorded throughput, latency, storage, and resource utilisation. The methodology is documented so you can reproduce it with your own payloads. ## At a glance * **Storage is linear and predictable: \~5.7 KB per encrypted 120-field record.** Multiply by your record count to size the volume (10 M β‰ˆ 59 GB, 100 M β‰ˆ 585 GB). * **Index size scales with how many fields you make searchable β€” plan for *your* field set.** This benchmark indexed **only `email`** (plus the always-present `token` and retention indexes) β†’ \~139 bytes/record. **Each additional searchable field you index (`phone`, `login`, `custom`) adds another index: budget roughly +40–50 bytes/record and more write CPU per field.** Size the database RAM to cache *all* your indexes (with email only, 100 M β‰ˆ 14 GB; cache-hit β‰₯ 97%). * **Detokenisation is fast: \~14 ms** per single-record `UserGet`, regardless of vault size. * **Write throughput depends on scale.** At small scale it is limited by the **application tier** and one instance does \~5,800 records/sec. At tens of millions of rows it is limited by **database CPU** and plateaus at **\~12,000 records/sec** β€” so you size the **database** for large vaults, not the app tier. * **Rule of thumb:** pick your database and application instances from the [sizing guide](#how-to-size-your-deployment) by record count. For most workloads a single Databunker Pro instance is already more than enough. ## What we measured Three runs, same workload, increasing scale. In every run Databunker Pro (stateless, in Docker) ran on EC2 with the load generator co-located, writing to a **dedicated RDS PostgreSQL 16** instance in the same VPC (`eu-central-1`). Multiple app instances share one database and one wrapping key. | Run | Records | Application tier | Dedicated RDS database | Write result | | ----- | ------- | ----------------- | ----------------------------------- | ----------------------------------- | | **A** | 10 M | 1 Γ— `m6i.2xlarge` | `db.m6i.2xlarge` β€” 8 vCPU / 32 GB | \~5,800 rec/s β€” **app-bound** | | **B** | 50 M | 4 Γ— `m6i.2xlarge` | `db.m6i.4xlarge` β€” 16 vCPU / 64 GB | \~11,800 rec/s β€” **database-bound** | | **C** | 100 M | 5 Γ— `m6i.2xlarge` | `db.m6i.8xlarge` β€” 32 vCPU / 128 GB | \~11,900 rec/s β€” **database-bound** | **Common workload** * **Profile:** 120 fields per record (mixed PII + custom application fields). * **Write path:** `UserCreateBulk` at **4,000 records/request, 8 concurrent workers per instance**. * **Storage & encryption:** gp3 volumes; **AES-256 at rest, TLS in transit** (defaults). * **Indexes per record:** every user always has a unique **token** index (the detokenisation lookup) and a **retention** (`finaltime`) index. Search fields add one salted-hash index each β€” this benchmark sets only `email`, giving **three indexes/record** (\~139 bytes total). Databunker Pro can also index `phone`, `login`, and `custom` (a hashed index is written only when the field is present); setting those adds per-insert database CPU and lowers sustained write throughput at scale. `name` and the other profile fields are encrypted but not indexed. * **Placement:** loaders co-located with Databunker Pro (no client-side network noise); the only network hop measured is **App β†’ RDS**. Redis is used only for transient session state and is **not** exercised by bulk writes; a production deployment points all instances at a shared Redis cluster. A separate 5 M run with PostgreSQL **co-located** on the app host managed only \~1,700 rec/s β€” moving to a **dedicated** database roughly tripled write throughput, which is why every run here uses dedicated RDS. ## Results | Records | DB size | Per-record | Indexes | Sustained bulk write | Detok p50 | Bottleneck | | --------- | --------- | ---------- | ------- | -------------------------------- | --------- | ------------------------ | | **10 M** | 58.5 GB | \~5.7 KB | 1.4 GB | **\~5,800 rec/s** (1 instance) | \~14 ms | app tier (RDS \~20% CPU) | | **50 M** | 292 GB | \~5.7 KB | 6.9 GB | **\~11,800 rec/s** (4 instances) | β€” | database (RDS \~80% CPU) | | **100 M** | 584 GB | \~5.7 KB | 13.9 GB | **\~11,900 rec/s** (5 instances) | β€” | database (RDS \~82% CPU) | | 150 M | \~875 GB | \~5.7 KB | \~21 GB | database-bound *(projected)* | β€” | database | | 200 M | \~1.17 TB | \~5.7 KB | \~28 GB | database-bound *(projected)* | β€” | database | All runs completed with **zero failed batches**. Per-record storage is essentially constant across scale β€” storage planning is simple linear math. ## The key insight: the bottleneck moves with scale This is the single most important thing to understand when sizing Databunker Pro. **At small scale, the application tier is the limit.** Encrypting and hash-indexing each record is CPU work done by Databunker Pro. At 10 M records one instance used \~3.2 of its 8 cores while the database sat at just \~20% CPU. Here, **adding Databunker Pro instances raises throughput** β€” the stateless app tier scales cleanly (we verified near-linear scaling from 1 to 6 instances on a small vault), and the database has plenty of headroom. **At large scale, the database CPU is the limit.** As the table grows, every insert costs the database more (deeper B-tree indexes, page splits, WAL, autovacuum). By tens of millions of rows this dominates: | | 10 M (1 instance) | 50 M (4 instances) | 100 M (5 instances) | | ------------------------ | ------------------------- | -------------------------- | -------------------------- | | RDS instance | `db.m6i.2xlarge` (8 vCPU) | `db.m6i.4xlarge` (16 vCPU) | `db.m6i.8xlarge` (32 vCPU) | | **RDS CPU (avg / peak)** | **20% / 33%** | **80% / 95%** | **82% / 95%** | | Aggregate write | \~5,800 rec/s | \~11,800 rec/s | \~11,900 rec/s | | App CPU (per instance) | \~3.2 cores | saturating DB | saturating DB | **Throughput plateaus at \~12,000 records/sec.** Note that 50 M and 100 M delivered almost the same throughput **even though the 100 M run used twice the database vCPU** (32 vs 16). Doubling the database didn't help because the per-insert cost had also doubled with the larger index. To push past this plateau, database vCPU has to grow *faster* than the table. **What this means for you:** * **Steady-state and real-time workloads** are nowhere near these limits β€” one Databunker Pro instance on a modest database handles them comfortably. * **Bulk backfills of very large vaults are database-bound and take hours** (100 M β‰ˆ \~2.3 h here). Size the **database** for the row count, and don't expect more app instances to speed it up once RDS is CPU-saturated. ## How to size your deployment Pick the row you're targeting. Storage scales at \~5.7 KB/record. Index RAM depends on **how many fields you index** β€” the numbers below assume the benchmark's set (`token` + retention + **one** search index, `email`) β‰ˆ \~139 bytes/record; **add \~40–50 bytes/record for each extra searchable field** you index (`phone`, `login`, `custom`). The database instance is the throughput limiter at scale, so it's sized for **vCPU (write speed) and RAM (index cache)**. Application nodes are stateless `m6i.2xlarge` (Databunker Pro uses \~3 vCPU at full load) β€” add them to speed up bulk loads only until the database reaches \~70–80% CPU. | User records | RDS database instance | RDS storage (gp3) | Index size, **email only** (vs instance RAM) | App instances | Confidence | | ------------- | ----------------------------------------- | ----------------- | -------------------------------------------- | ------------------- | ---------------- | | **≀ 10 M** | `db.m6i.2xlarge` β€” 8 vCPU / 32 GB | 150 GB | \~2 GB (of 32) | 1 Γ— `m6i.2xlarge` | measured | | **10–50 M** | `db.m6i.4xlarge` β€” 16 vCPU / 64 GB | 500 GB | \~7 GB (of 64) | 2–4 Γ— `m6i.2xlarge` | measured @ 50 M | | **50–100 M** | `db.m6i.8xlarge` β€” 32 vCPU / 128 GB | 1 TB | \~14 GB (of 128) | 4–5 Γ— `m6i.2xlarge` | measured @ 100 M | | **100–150 M** | `db.r6i.8xlarge` β€” 32 vCPU / 256 GB | 1.1 TB | \~21 GB (of 256) | 4–5 Γ— `m6i.2xlarge` | projected | | **150–200 M** | `db.r6i.8xlarge` or **Aurora PostgreSQL** | 1.3–1.5 TB | \~28 GB | 4–6 Γ— `m6i.2xlarge` | projected | The **index column is for the benchmark's index set only** (`token` + retention + the single `email` search index). Note the large headroom β€” 14 GB of indexes on a 128 GB instance β€” because these instances are chosen for **write vCPU**, not index RAM, so they hold several more indexes comfortably. **If you index more fields, recompute:** \~139 bytes/record (email only) **+ \~40–50 bytes/record per additional searchable field** (`phone`, `login`, `custom`), Γ— your record count, and confirm it still fits in RAM. Storage and write vCPU are unaffected by this β€” only index RAM and per-insert write cost grow. **Three sizing rules** 1. **Storage** = 5.7 KB Γ— records, plus **30–40% headroom** for WAL, bloat, and backups. 2. **RAM** must exceed your **total index size + hot rows** so lookups stay cached. Index storage = `token` + retention + **one per searchable field**. With only `email` indexed this was \~139 bytes/record (100 M β‰ˆ 14 GB; cache-hit β‰₯ 97%); **add \~40–50 bytes/record for every extra field you index** (`phone`, `login`, `custom`). Multiply by your record count. 3. **Database vCPU** is the sustained-write limiter at scale β€” grow it (or move to **Aurora** for storage auto-scaling and read replicas) before adding app instances once RDS passes \~70% CPU. ## Reads: detokenisation latency Detokenisation (`UserGet`) is a hashed-index point lookup by token, measured against the fully-loaded 10 M vault: | Metric | Value | | ---------------------------- | ----------------------------------------------------------- | | **Latency p50 / p95 / p99** | **\~14 ms / \~15 ms / \~16 ms** per single-record `UserGet` | | Read throughput (1 instance) | \~660 reads/sec synchronous (16 concurrent clients) | Latency is dominated by the round trip (HTTP, auth, index lookup, decryption), **not** index depth β€” the index cache-hit ratio stayed β‰₯ 97% at every scale, so lookups are served from memory. Read **throughput** scales horizontally: add Databunker Pro instances (and, for very large vaults, database read replicas) to serve more concurrent lookups. ## Storage footprint Encrypted profile blobs dominate the footprint; indexes are comparatively small (which is why a modest amount of RAM keeps them cached). | Component | 10 M | 100 M | Per record | | ------------------------------ | ------- | -------- | ------------ | | Total database size | 58.5 GB | 584 GB | **\~5.7 KB** | | Encrypted profile data (TOAST) | \~55 GB | \~550 GB | \~5.5 KB | | Heap (`users` table) | 1.8 GB | \~9 GB | \~90 B | | **Indexes β€” email only** | 1.4 GB | 13.9 GB | **\~139 B** | The two figures that scale with your design: * **Encrypted profile data** grows with **payload size** β€” a bigger/smaller profile than our 120-field one moves the \~5.5 KB/record directly. * **Indexes** grow with **how many fields you make searchable.** The \~139 B/record above is the benchmark's set only β€” `token` (always) + retention + the single `email` search index. **Add \~40–50 B/record for each additional indexed field** (`phone`, `login`, `custom`). Storage total, heap, and per-record profile size are unaffected by indexing choices β€” only the index line (and per-insert write CPU) grows. ## Write latency: bulk vs single record The \~0.17 ms per record at 10 M is **amortised inside a 4,000-record bulk request**. Individual `UserCreateBulk` calls take longer end-to-end (p50 \~4.5 s for a 4,000-record batch at 10 M, growing with table size), and **single-record synchronous writes** are typically 3–10 ms over a real network because each call carries its own connection, auth, and transaction overhead. * **Backfills / batch flows:** use `UserCreateBulk`. * **Real-time API flows:** assume single-digit-millisecond single-record writes; production throughput = `concurrency Γ· per-call latency`. ## Reproduce this benchmark Start from the open-source Python load scripts in the [`databunkerpro-python`](https://github.com/securitybunker/databunkerpro-python) SDK repo: * **[`bulk_user_creator.py`](https://github.com/securitybunker/databunkerpro-python/blob/main/bulk_user_creator.py)** β€” drives `UserCreateBulk`. * **[`bulk_user_fetcher.py`](https://github.com/securitybunker/databunkerpro-python/blob/main/bulk_user_fetcher.py)** β€” drives `UserGet` for read latency. Dedicated managed PostgreSQL (RDS / Aurora / Cloud SQL) plus a separate application host in the same VPC. Edit the profile shape in `bulk_user_creator.py` to the JSON your application actually sends. Run the loader co-located with Databunker Pro, with multiple concurrent workers (and multiple instances for large loads). Record sustained records/sec, p50/p95/p99 bulk latency, **database CPU and IOPS**, and **application-tier CPU** β€” whichever is saturated is your bottleneck. Run `bulk_user_fetcher.py` against the same vault to capture `UserGet` latency and throughput. Your numbers will vary with payload size, number of search indexes, access-control policy depth, and database instance/IOPS. Contact [office@databunkertech.com](mailto:office@databunkertech.com) if you'd like the professional-services team to run a benchmark against your representative payloads. ## Scope & roadmap These runs cover the **PII vault write path** (`UserCreateBulk`) and the **detokenisation read path** (`UserGet`). They do **not** cover the secure session-storage API, format-preserving tokenisation, or agreement/legal-basis flows β€” those have different characteristics and are measured separately. Coming next: 150 M–200 M measured runs (to replace the projected sizing rows), secure session-storage API, format-preserving tokenisation throughput, and a MySQL backend comparison. # PII Vault - PII Storage & Tokenization in Databunker Pro Source: https://docs.databunker.org/pro/get-started/pii-vault In today's data-driven world, protecting personally identifiable information (PII) isn't just a compliance requirementβ€”it's a business imperative. Databunker Pro's PII Vault provides enterprise-grade secure storage and tokenization for sensitive personal data, enabling organizations to build privacy-by-design solutions while maintaining operational efficiency. When sensitive data enters your system, Databunker instantly encrypts, tokenizes, and stores it in a secure vault. You get back a safe token to store anywhere β€” even in public databases. You can run Databunker in the cloud or on-premises, you can enable your enterprise customers to self-host their PII vault in any region, which solves PII export restrictions and reduces compliance risk. ## πŸ” What is a PII Vault? The PII Vault is Databunker Pro's core feature that transforms how organizations handle sensitive personal data. Instead of storing PII directly in your application database, the PII Vault: * **Encrypts and tokenizes** entire user records using AES-256 encryption * **Generates secure UUID tokens** that can be safely stored anywhere * **Maintains searchable indexes** using secure hash-based lookups * **Provides audit trails** for every data access and modification * **Enables compliance** with GDPR, HIPAA, SOC2, and other privacy regulations ## ⚠️ Why Use PII Vault Instead of Regular Database Tables? ### Traditional Database Approach Problems ```sql theme={null} -- Traditional approach: PII stored in plain text or basic encryption CREATE TABLE users ( id SERIAL PRIMARY KEY, email VARCHAR(255), -- Exposed in logs, backups, queries first_name VARCHAR(100), -- Visible to all database users last_name VARCHAR(100), -- Accessible via SQL injection phone VARCHAR(20), -- Stored in application logs ssn VARCHAR(11), -- High-risk data exposure created_at TIMESTAMP ); ``` **Issues with this approach:** * ❌ **Data exposure** in logs, backups, and error messages * ❌ **SQL injection vulnerabilities** expose sensitive data * ❌ **Database admin access** reveals all personal information * ❌ **Compliance complexity** requires extensive additional controls * ❌ **Breach impact** exposes all stored PII immediately ### Databunker Pro PII Vault Solution Instead of storing PII in your application database, store only the user secure tokens (in UUID format): ```sql theme={null} -- Modern approach: Only tokens stored in application database CREATE TABLE users ( id SERIAL PRIMARY KEY, user_token UUID -- Safe to store anywhere ); ``` **Benefits of this approach:** * βœ… **Zero PII exposure** in application databases, logs, or backups * βœ… **Breach protection** - attackers only see meaningless tokens * βœ… **Built-in compliance** with privacy regulations * βœ… **Simplified architecture** - no complex encryption management * βœ… **Audit-ready** with comprehensive access logging ## βš™οΈ How PII Vault Works ### 1. Data Ingestion and Tokenization When sensitive data enters your system, Databunker Pro: 1. **Accepts complete user profiles** in JSON format 2. **Extracts searchable fields** (email, phone, login, custom) for indexing 3. **Encrypts the entire record** using AES-256 encryption 4. **Generates a secure UUID token** for the record 5. **Stores encrypted data** in the secure vault 6. **Creates hashed search indexes** for efficient lookups ### 2. Uniqueness and identity resolution The hashed search indexes on `email`, `phone`, `login`, and `custom` are **unique within a tenant**. This has three practical consequences: * **Duplicates cannot coexist inside the same tenant.** A second attempt to create a user record under an existing email / phone / login / custom value is rejected at the vault level β€” identity uniqueness is a structural guarantee, not a discipline. * **Repeat identities resolve to the same token.** When the same person appears again, look them up by their indexed field and reuse the existing token; there is no risk of accidentally minting two tokens for the same underlying identity. * **Different tenants can hold their own record for the same person.** Tenants are cryptographically isolated boundaries (PostgreSQL row-level security), so the same email tokenised in two tenants produces two different tokens β€” this is the basis of the multi-tenant, multi-token pattern used for separating analytics, operational, and external-integration domains. Together, these properties mean that **tokens within a tenant are stable, deterministic join keys** β€” SQL queries that previously joined on `email` can join on `user_token` with no round-trip to the vault. ### 3. Secure Storage Architecture Databunker Architecture ## πŸ’» Code Examples: Storing and Retrieving User Records ### Storing User PII **REST API Example:** ```bash theme={null} curl -X POST https://your-databunker-pro/v2/UserCreate \ -H "X-Bunker-Token: YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "profile": { "email": "john.doe@example.com", "first": "John", "last": "Doe", "phone": "+1-555-123-4567", "ssn": "123-45-6789", "address": "123 Main St, City, State 12345", "dob": "1985-06-15" } }' ``` **Response:** ```json theme={null} { "status": "ok", "token": "a21fa1d3-5e47-11ef-a729-32e05c6f6c16" } ``` **JavaScript/Node.js Example:** ```javascript theme={null} const axios = require("axios"); async function storeUserPII(userData) { try { const response = await axios.post( "https://your-databunker-pro/v2/UserCreate", { profile: { email: userData.email, first: userData.firstName, last: userData.lastName, phone: userData.phone, ssn: userData.ssn, address: userData.address, dob: userData.dateOfBirth, }, }, { headers: { "X-Bunker-Token": process.env.DATABUNKER_API_KEY, "Content-Type": "application/json", }, } ); return response.data.token; // Store this token in your database } catch (error) { console.error("Error storing user PII:", error); throw error; } } // Usage const userToken = await storeUserPII({ email: "jane.smith@example.com", firstName: "Jane", lastName: "Smith", phone: "+1-555-987-6543", ssn: "987-65-4321", address: "456 Oak Ave, City, State 54321", dateOfBirth: "1990-03-22", }); ``` **Python Example:** ```python theme={null} import requests import json def store_user_pii(user_data): url = "https://your-databunker-pro/v2/UserCreate" headers = { "X-Bunker-Token": "YOUR_API_KEY", "Content-Type": "application/json" } payload = { "profile": { "email": user_data["email"], "first": user_data["first_name"], "last": user_data["last_name"], "phone": user_data["phone"], "ssn": user_data["ssn"], "address": user_data["address"], "dob": user_data["date_of_birth"] } } response = requests.post(url, headers=headers, json=payload) response.raise_for_status() return response.json()["token"] # Usage user_token = store_user_pii({ "email": "mike.johnson@example.com", "first_name": "Mike", "last_name": "Johnson", "phone": "+1-555-456-7890", "ssn": "456-78-9012", "address": "789 Pine St, City, State 67890", "date_of_birth": "1988-11-08" }) ``` ### Retrieving User PII **Retrieve by Token:** ```bash theme={null} curl -X POST https://your-databunker-pro/v2/UserGet \ -H "X-Bunker-Token: YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "mode": "token", "identity": "a21fa1d3-5e47-11ef-a729-32e05c6f6c16" }' ``` **Retrieve by Email:** ```bash theme={null} curl -X POST https://your-databunker-pro/v2/UserGet \ -H "X-Bunker-Token: YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "mode": "email", "identity": "john.doe@example.com" }' ``` **Retrieve by Phone:** ```bash theme={null} curl -X POST https://your-databunker-pro/v2/UserGet \ -H "X-Bunker-Token: YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "mode": "phone", "identity": "+1-555-123-4567" }' ``` ## πŸ›‘οΈ Enterprise Security Features Databunker Pro provides enterprise-grade security with **AES-256 encryption**, **role-based access control**, and **comprehensive audit logging**. Built-in compliance with **DPDPA, GDPR, HIPAA, SOC2, and PCI DSS** standards, plus **multi-tenant isolation** and **horizontal scaling** for enterprise deployment. ## 🎯 Conclusion Databunker Pro's PII Vault transforms how organizations handle sensitive data, providing enterprise-grade security that goes far beyond traditional database approaches. **Key Benefits:** * **πŸ”’ Zero PII Exposure** - Sensitive data never touches your application databases, logs, or backups * **⚑ Simplified Compliance** - Built-in GDPR, HIPAA, SOC2, and PCI DSS controls with automatic audit trails * **πŸ›‘οΈ Breach Protection** - Attackers only see meaningless tokens, not actual personal data * **πŸš€ Developer-Friendly** - Easy-to-use APIs that don't slow down development * **πŸ“ˆ Enterprise Scale** - Horizontal scaling with multi-region deployment options **The Bottom Line:** Instead of building complex security layers around your existing database, Databunker Pro's PII Vault eliminates the risk at the source. Your sensitive data stays secure in an encrypted vault while your applications work with safe tokens. Ready to eliminate PII exposure and simplify compliance? The PII Vault is the modern solution for privacy-by-design architecture. # Security overview Source: https://docs.databunker.org/pro/get-started/security-overview Information security's primary focus is the balanced protection of confidentiality, integrity, and availability of data. This document reviews Databunker Pro's security features based on these core principles. Databunker Pro is built following privacy-by-design principles, which are integral to **GDPR**, **CPRA**, and **SOC2** privacy standards. **Databunker Pro** allows you to build **privacy by design** compliant solutions, and to follow data minimization requirements. When using **Databunker Pro**, every API request generates an audit trail. **Databunker Pro** can be used as a **consent management system** and as a **repository for processing operations**. It serves as an external storage according to pseudonymization definition and complies with Schrems II cross-border personal data transfer implementation. Databunker Pro is the secure vault and tokenization engine. Data Protection Officer (DPO) operations β€” data-subject rights, SaaS and database connectors (HubSpot, MailChimp, Salesforce, MySQL, PostgreSQL, Oracle, SQL Server), and one-click personal data reports β€” are provided by the separate **Databunker DPO** product in the Databunker Portal. For global organisations running Pro in multiple jurisdictions, DPO also serves as the unifying operational layer across regional deployments β€” see [Multi-jurisdiction deployment](/pro/concepts/global-deployment). ## How we address confidentiality ### Encryption in transit and encryption at rest Databunker Pro enforces full encryption in transit and at rest by default. All network requests are secured using SSL encryption protocols. ### Record encryption Customer personal information records are encrypted using **AES-256** keys or securely hashed in the product internal database. AES-256 encryption is **FIPS 140-2 compliant** and meets federal cryptographic standards. ### Encryption of audit events Personally Identifiable Information (PII) in audit events is fully encrypted. ### Secure hash-based search index Databunker Pro extracts emails, phone numbers, and login names from user records to build a hashed-based search index. This method allows secure lookups of original user records. ### Backend database connectivity **Databunker Pro** supports both **PostgreSQL** and **MySQL** as backend databases, connecting through a **secure SSL channel**. Note: Multi-tenancy is only supported with PostgreSQL and is not available when using MySQL. ### FIPS compliance Databunker Pro uses **FIPS 140-2 compliant** cryptographic algorithms for core security operations: * **Certificate generation**: When deploying via Helm, certificates are generated using **RSA 2048-bit** key length, which is FIPS compliant. * **Record encryption**: All customer records are encrypted using **AES-256**, a FIPS-approved symmetric encryption algorithm. * **Go runtime**: The Go programming language runtime does not enforce FIPS mode internally, allowing Databunker Pro to operate in FIPS-enabled environments while maintaining compatibility. **Note on MD5 usage**: Databunker Pro uses MD5 for non-cryptographic purposes only: * As a distributed lock mechanism in the `users` and `userapps` tables to prevent concurrent modifications * As part of a double-hash (SHA256 + MD5) for duplicate detection in format-preserving tokenization engine * As salt material (MD5 of master key) for SHA256-based indexing of user records (e.g., email, phone numbers) These MD5 usages are for internal system operations and do not impact the FIPS compliance of cryptographic operations protecting customer data. ### Secure session storage Session data, including PII such as email addresses, IP addresses, and browser details, is securely stored in Databunker’s encrypted store via a dedicated API. ### Secure bulk data export/dump We have introduced a specialized secure API to control and limit bulk data exports. Learn more here. ### Wrapping keys and Shamir key shares Databunker Pro uses a **Master key** to encrypt all records. The Master Key is never exposed. In Databunker Pro, the master key is further secured using a **Wrapping key**. The wrapping key can be rotated via API, and its backup is divided into parts using the Shamir key sharing algorithm for recovery if lost or compromised. ### Optional user scheme validation Databunker Pro supports user schema validation to enforce mandatory fields in user records. It returns error messages for objects missing required fields. ## How we address integrity ### Record update Databunker employs encrypted JSON objects for storing user profiles. During updates, Databunker ensures the presence of the original record in the database by verifying its checksum before executing SQL UPDATE queries. ### Multi-tenancy Databunker Pro implements [multi-tenancy](/pro/administration/multi-tenancy) using PostgreSQL's row-level security mechanism. Queries executed by specific tenants are restricted to their own records. **Note:** Multi-tenancy requires PostgreSQL and is not supported with MySQL. ### Token-based API Access All API requests require a user token and tenant name. Databunker identifies user roles, verifies permissions, and blocks unauthorized requests within the tenant’s scope. ## How we address availability ### Containers Databunker Pro is distributed as Docker container, which can be easily deployed in cloud environments. Example scripts for running these containers using Docker Compose and Kubernetes are provided. ### Stateless application server Databunker Pro is a stateless application server, enabling multiple instances to run concurrently. The primary bottleneck is the backend database. To address this, Databunker Pro integrates with AWS Aurora PostgreSQL Auto-Scaling databases. Both PostgreSQL and MySQL are supported as backend databases. ### Scalability in Kubernetes Databunker Pro can be seamlessly scaled in Kubernetes using horizontal scaling. This ensures high availability and performance under increasing workloads. Kubernetes facilitates effortless scaling by dynamically adjusting the number of running instances based on resource utilization, ensuring that Databunker can meet growing demands efficiently. # Clean the users table Source: https://docs.databunker.org/pro/howtos/clean-users-table Remove all user records and related data from a Databunker Pro instance. This guide explains how to wipe **all** user data from a Databunker Pro instance while keeping its configuration (tenants, roles, policies, encryption keys, license) intact. It is intended for resetting a **test**, **staging**, or **to-be-decommissioned** instance. This operation is destructive and irreversible. It deletes every user across **all tenants** β€” the SQL `TRUNCATE` command ignores row-level security, so it cannot be limited to a single tenant. Never run it against a production database. Take a backup first. ## Background A user in Databunker Pro is identified by a UUID **token**. Beyond the main `users` table, the same token (or, for a few tables, the `usertoken` / `record` column) links a user to several auxiliary tables. A full cleanup must clear all of them: | Table | User column | Contents | | ----------------- | ----------- | ----------------------------------------------------------------------- | | `users` | `token` | Main encrypted user profile | | `userapps` | `token` | Per-user app records | | `userappversions` | `token` | App record version history | | `userversions` | `token` | User profile version history | | `usergroups` | `token` | Group memberships | | `sessions` | `token` | User sessions | | `sharedrecords` | `token` | Shared-record grants | | `requests` | `token` | Data-subject requests | | `agreements` | `token` | Consent / legal-basis agreements | | `audit` | `record` | Audit events for the user | | `xtokens` | `usertoken` | Per-user access tokens (only rows where `usertoken` is set β€” see below) | The tokenization vault (`tokens`) is **not** keyed by user token and is left out by default β€” see [Tokenization vault](#tokenization-vault) below. ## Before you start * Direct (`psql`) access to the PostgreSQL database backing Databunker Pro. * A recent backup. ## Truncate all user tables Run the following statements. `RESTART IDENTITY` resets the auto-increment sequences (only `usergroups` actually uses one) so a fresh instance starts clean. ```sql theme={null} TRUNCATE TABLE users RESTART IDENTITY; TRUNCATE TABLE userapps RESTART IDENTITY; TRUNCATE TABLE userappversions RESTART IDENTITY; TRUNCATE TABLE userversions RESTART IDENTITY; TRUNCATE TABLE usergroups RESTART IDENTITY; TRUNCATE TABLE sessions RESTART IDENTITY; TRUNCATE TABLE sharedrecords RESTART IDENTITY; TRUNCATE TABLE requests RESTART IDENTITY; TRUNCATE TABLE agreements RESTART IDENTITY; TRUNCATE TABLE audit RESTART IDENTITY; DELETE FROM xtokens WHERE usertoken IS NOT NULL AND usertoken::text <> ''; ``` `TRUNCATE` empties the tables in a single fast operation and reclaims disk space immediately, so a follow-up `VACUUM` is not required. Do **not** `TRUNCATE` the `xtokens` table. It holds the **root** and **role** access tokens (rows where `usertoken` is `NULL`) alongside the per-user login tokens. Wiping it would invalidate the root token and lock you out of the API. Delete only the rows that belong to a user with `DELETE FROM xtokens WHERE usertoken IS NOT NULL AND usertoken::text <> '';`, as shown above β€” this preserves the root and role tokens. `TRUNCATE` ignores row-level security, so it always clears every tenant regardless of the `my.tenantid` session setting. If you need to remove the users of a single tenant only, delete by `tenantid` with `DELETE` statements instead of truncating. ## Tokenization vault If you use [tokenization](/pro/concepts/tokenization), a user's sensitive fields may be stored in the `tokens` vault. This table is **not** keyed by the user token, so it is intentionally excluded above to avoid breaking tokens that are still referenced elsewhere. Truncate it only if you want to erase the entire vault as part of a full reset: ```sql theme={null} -- Empties the tokenization vault. It is RANGE-partitioned; -- truncating the parent cascades to tokens_p0..p240. TRUNCATE TABLE tokens RESTART IDENTITY; ``` ## What is preserved The following configuration tables are **not** touched, so the instance stays usable after the cleanup: `tenants`, `config` (including the license key), `encryptionkeys`, `policies`, `roles`, `rolepolicies`, `groups`, `connectors`, `legalbasis`, and `processingactivities`. # How-tos overview Source: https://docs.databunker.org/pro/howtos/overview Short, task-focused guides for common Databunker Pro operations. This section collects short, task-focused guides for operations you perform against a running Databunker Pro instance. ## Available how-tos * [Update the license key](/pro/howtos/update-license) β€” apply a new license to a running instance via the API or the web interface. * [Clean the users table](/pro/howtos/clean-users-table) β€” remove all user records and related data for a full reset (testing, staging, or decommissioning). These guides assume you already have Databunker Pro [installed](/pro/installation/docker-compose) and an admin (root) access token. See [Generate admin credentials](/pro/installation/generate-admin-credentials) if you have not completed the initial setup. # Update the license key Source: https://docs.databunker.org/pro/howtos/update-license Apply a new license key to a running Databunker Pro instance. Databunker Pro stores its license key in the database (the `config` table, under the `licensekey` key). You can replace it at any time on a running instance β€” there is no need to restart the service or redeploy. A new license is typically applied when you: * Move from **Trial** mode to a paid license. * Renew a license that is about to expire. * Increase the maximum number of records (`maxrecords`) your plan allows. Only the **main tenant** administrator (root token, tenant id `1`) can set the license key. The new key is validated before it is saved β€” an invalid or expired key is rejected and the existing license stays in place. ## Before you start To complete this guide, you'll need: * A running Databunker Pro instance. * The **root access token** of the main tenant. See [Generate admin credentials](/pro/installation/generate-admin-credentials). * A valid license key. [Book a call](https://cal.com/databunker-team/30min) to obtain or renew one. ## Update via the API Send the new key to the `SystemSetLicenseKey` endpoint. All Databunker Pro API calls use `POST /v2/` and authenticate with the `X-Bunker-Token` header. ```bash theme={null} curl -X POST http://localhost:3000/v2/SystemSetLicenseKey \ -H "X-Bunker-Token: YOUR-ROOT-TOKEN" \ -H "Content-Type: application/json" \ -d '{"licensekey": "YOUR-NEW-LICENSE-KEY"}' ``` A successful response looks like this: ```json theme={null} { "status": "ok", "result": "done" } ``` If the key is invalid or expired, the call returns an error and the current license is left unchanged: ```json theme={null} { "status": "error", "message": "License key is invalid" } ``` You can pre-load a license at first start with the `DATABUNKER_LICENSEKEY` environment variable. This is only used during the initial setup; once a key is stored in the database, update it using the API call above. # Install with Docker Compose Source: https://docs.databunker.org/pro/installation/docker-compose This page walks you through the steps to install Databunker Pro using Docker Compose. ## Before you start To complete this guide, you'll need [Docker Compose](https://docs.docker.com/compose/install/) installed on your computer. To confirm if Docker Compose is available, run the following command: ```sh theme={null} docker compose version ``` ## Clone the setup repository The repository contains configuration and helper scripts to help you get started. ```sh theme={null} git clone https://github.com/securitybunker/databunkerpro-setup.git cd databunkerpro-setup ``` ## Generate configuration files In this step, you'll generate a set of environment files that will be used to configure each of the services deployed by Docker Compose. This determines the database that Docker Compose should deploy. You don't need an existing database. ```sh theme={null} cd docker-compose-pgsql ``` ```sh theme={null} cd docker-compose-mysql ``` The following command will create a `.env` directory containing environment files for each Docker Compose service. ```sh theme={null} ./generate-env-files.sh ``` ## Deploy Databunker Pro using Docker Compose ```sh theme={null} docker compose up -d ``` In your browser, open [localhost:3000](http://localhost:3000) to access the Databunker web interface. For detailed instructions, see [Generate admin credentials](/pro/installation/generate-admin-credentials). To stop all Docker Compose services and clean up resources, run the following command: ```sh theme={null} docker compose down ``` # Generate admin credentials Source: https://docs.databunker.org/pro/installation/generate-admin-credentials This page explains the steps needed to set up Databunker Pro for the first time. ## Before you start To complete this guide, you'll need: * Databunker Pro installed * *(Optional)* A Databunker Pro License Key. Automating your deployment? You can complete this setup over the API without a browser β€” see [Unattended installation](/pro/installation/unattended-installation). ## Copy the generated access code from the logs When Databunker Pro starts for the first time, it generates a six-digit access code and outputs it to the service logs. For example, if you deployed Databunker Pro on Kubernetes, you can print the access code with the following command line: ```sh theme={null} kubectl logs deployment/databunkerpro | grep "Access code" ``` ## Complete the setup in your browser To complete the setup, you'll need access to the Databunker Pro web interface from your browser. By default, the web interface is exposed on port 3000. [Book a call](https://cal.com/databunker-team/30min) to purchase a license key, or leave empty to run Databunker Pro in Trial mode. Initial setup for Databunker Pro Copy the following secrets from the page and store them securely: * Root Access Token * Wrapping Key * Shamir Key Shares A setup page displaying root access token and encryption keys Finally, click **Start Databunker Pro** to start the service. Databunker Pro is now running and ready to use. Next, learn how to issue scoped credentials in the [Authentication reference](/pro/api/authentication). # Install with Kubernetes using Helm Source: https://docs.databunker.org/pro/installation/kubernetes-helm This page walks you through the steps to install Databunker Pro on Kubernetes using Helm. ## Before you start To complete this guide, you'll need: * [Kubernetes](https://kubernetes.io/docs/setup/) installed * [Helm](https://helm.sh/docs/intro/install/) installed ## Set up the Helm repository In this step, you'll set up the Databunker Pro Helm repository so that you can download the latest Helm charts. ```sh theme={null} helm repo add databunkerpro https://securitybunker.github.io/databunkerpro-setup ``` ```sh theme={null} helm repo list ``` You'll see the following output: ```plain theme={null} NAME URL databunkerpro https://securitybunker.github.io/databunkerpro-setup ``` ```sh theme={null} helm repo update ``` You can find the Helm charts in the [databunkerpro-setup](https://github.com/securitybunker/databunkerpro-setup) repository. ## Deploy Databunker Pro using Helm ```sh theme={null} helm install databunkerpro databunkerpro/databunkerpro ``` ```sh theme={null} kubectl port-forward service/databunkerpro 3000:3000 ``` For more information about port-forwarding in Kubernetes, see [Use Port Forwarding to Access Applications in a Cluster](https://kubernetes.io/docs/tasks/access-application-cluster/port-forward-access-application-cluster/). In your browser, open [localhost:3000](http://localhost:3000) to access the Databunker web interface. For detailed instructions, see [Generate admin credentials](/pro/installation/generate-admin-credentials). # Unattended installation Source: https://docs.databunker.org/pro/installation/unattended-installation Complete the Databunker Pro first-time setup automatically over the API β€” no browser required β€” for CI/CD, infrastructure-as-code, and reproducible deployments. The [browser-based setup](/pro/installation/generate-admin-credentials) is the easiest way to install Databunker Pro by hand. For automated, repeatable deployments β€” CI/CD pipelines, infrastructure-as-code, container orchestration β€” Databunker Pro exposes a **`POST /autoinstall`** endpoint that performs the same first-time setup **without a browser**. This guide shows how to complete the install programmatically and capture the generated credentials. ## Before you start * Databunker Pro **deployed** (see [Docker Compose](/pro/installation/docker-compose) or [Kubernetes / Helm](/pro/installation/kubernetes-helm)). * The **`DATABUNKER_SETUPKEY`** environment variable set on the Databunker Pro container β€” this enables the `/autoinstall` endpoint (details below). * A reachable database. If you use a **dedicated / managed database** (e.g. AWS RDS), create the `databunkerdb` database and roles first β€” see [Using an external database](#using-an-external-database). * *(Optional)* a Databunker Pro **license key**. Without one, Databunker Pro runs in Trial mode. ## How it works Unattended installation is three HTTP calls against the Databunker Pro service: 1. **`GET /status`** β€” wait until the service is up. 2. **`GET /dbstatus`** β€” check whether setup is still required (`{"installed": false}`). 3. **`POST /autoinstall`** β€” perform the setup and return the credentials. **Setup endpoints are ephemeral.** While the vault is not yet installed, Databunker Pro runs a small **setup server** that hosts `/dbstatus`, `/setup`, and `/autoinstall`. As soon as setup completes, that server shuts down and the container **restarts in normal operational mode** β€” where only the regular API (`/status`, `/v2/*`) is served and **`/dbstatus` returns `404`**. That 404 is expected: it means the vault is already installed. (`/dbstatus` only ever returns a boolean `installed` flag β€” no sensitive data.) The install runs once: call `/autoinstall` **only** when `/dbstatus` explicitly returns `installed: false`; treat a `404`, a connection error, or any other response as **"already installed β€” skip."** ## Enable the setup endpoint The `/autoinstall` endpoint is only available when a setup key is configured. Set **`DATABUNKER_SETUPKEY`** (and the persistent **`DATABUNKER_WRAPPINGKEY`**) in the container environment before starting Databunker Pro β€” for Docker Compose, in `.env/databunker.env`: ```sh theme={null} DATABUNKER_WRAPPINGKEY=<48-hex-character master key> DATABUNKER_SETUPKEY= ``` Treat `DATABUNKER_SETUPKEY` as a **credential** β€” anyone who can reach the service with it can initialise the vault. Use a long random value, keep it in your secrets manager, and restrict network access to the service during setup. ## Run the unattended install Poll `GET /status` until it returns `200 OK`: ```sh theme={null} until curl -fsS http://localhost:3000/status >/dev/null; do sleep 2; done ``` ```sh theme={null} curl -s http://localhost:3000/dbstatus ``` Only `{"status":"ok","installed":false}` means setup is needed. Any other outcome β€” `installed: true`, a **`404`** (the setup server has already shut down), or a connection error β€” means the vault is already installed, so **skip `/autoinstall`**. Send the setup key (and optional license key) as form fields: ```sh theme={null} SETUPKEY=$(grep '^DATABUNKER_SETUPKEY=' .env/databunker.env | cut -d= -f2-) curl -s -X POST http://localhost:3000/autoinstall \ --data-urlencode "setupkey=$SETUPKEY" \ --data-urlencode "licensekey=$LICENSEKEY" # optional; omit for Trial mode ``` Use `--data-urlencode` (not `-d`): license keys are base64 and may contain `+` or `/`, which `-d` would corrupt. ```python theme={null} import time import requests BASE = "http://localhost:3000" SETUPKEY = "..." # value of DATABUNKER_SETUPKEY LICENSEKEY = "" # optional; leave empty for Trial mode # 1. wait until ready for _ in range(30): try: if requests.get(f"{BASE}/status", timeout=5).ok: break except requests.ConnectionError: pass time.sleep(2) # 2. install only if the vault explicitly reports installed=false. # A 404 / error means the setup server is gone -> already installed -> skip. def needs_install() -> bool: try: return requests.get(f"{BASE}/dbstatus", timeout=10).json().get("installed") is False except Exception: return False if needs_install(): body = {"setupkey": SETUPKEY} if LICENSEKEY: body["licensekey"] = LICENSEKEY resp = requests.post(f"{BASE}/autoinstall", data=body, timeout=30).json() assert resp.get("status") == "ok" and resp.get("root_token"), resp # 3. persist resp securely β€” see next step save_credentials(resp) else: print("Databunker Pro already installed β€” skipping autoinstall") ``` On success the response contains the vault credentials: ```json theme={null} { "status": "ok", "root_token": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx", "wrapping_key": "...", "shamir_keys": ["...", "...", "...", "...", "..."] } ``` Store all of these in your secrets manager immediately. These secrets are shown **once** and cannot be retrieved again. The **`root_token`** is your admin credential β€” you pass it as the `X-Bunker-Token` header on every administrative API call. Losing it means re-installing. ## Verify The setup server restarts the container in normal mode. Confirm it is serving, then use the root token for API calls: ```sh theme={null} curl -fsS http://localhost:3000/status ``` ```sh theme={null} curl -s -X POST http://localhost:3000/v2/SystemGetSystemStats \ -H "X-Bunker-Token: $ROOT_TOKEN" ``` ## Using an external database The bundled Docker Compose project provisions the `databunkerdb` database and its roles automatically. When you point Databunker Pro at a **dedicated / managed** database (AWS RDS, Cloud SQL, Azure Database), create them yourself first β€” connect as the database master user and run: ```sql theme={null} CREATE ROLE bunkeruser NOSUPERUSER LOGIN PASSWORD ''; CREATE ROLE mtenant NOSUPERUSER NOLOGIN; CREATE ROLE madmin BYPASSRLS NOSUPERUSER NOLOGIN; CREATE DATABASE databunkerdb OWNER bunkeruser; -- then, connected to databunkerdb: GRANT ALL ON SCHEMA public TO bunkeruser; GRANT mtenant TO bunkeruser; GRANT madmin TO bunkeruser; ``` Point the container at the database with the `PGSQL_HOST`, `PGSQL_USER_NAME`, `PGSQL_USER_PASS`, and `PGSQL_SSL_MODE` environment variables, then run the unattended install as above. If you run **multiple Databunker Pro instances** against one shared database, they must all use the **same `DATABUNKER_WRAPPINGKEY`** (only one instance runs `/autoinstall`; the others start against the already-installed database). The wrapping key must persist across restarts, or the vault cannot be reopened. ## Next steps * [Update your license key](/pro/howtos/update-license) at any time after install. * Rotate and back up your [master (wrapping) key](/pro/administration/master-key) and [Shamir key shares](/pro/administration/shamir-keys). * Learn how to issue scoped credentials in the [Authentication reference](/pro/api/authentication).