diff --git a/.github/workflows/Gitleaks.yml b/.github/workflows/Gitleaks.yml new file mode 100644 index 00000000..9807b5e9 --- /dev/null +++ b/.github/workflows/Gitleaks.yml @@ -0,0 +1,97 @@ +name: Gitleaks secrets scan + +on: + pull_request: + branches: + - main + + +permissions: + issues: write + pull-requests: write + contents: read + +jobs: + gitleaks: + runs-on: ubuntu-latest + + steps: + - name: Checkout code + uses: actions/checkout@v4 + with: + fetch-depth: 0 # Required to get full commit history for diffing + + + - name: Get base and head commit SHAs + run: | + echo "BASE_SHA=${{ github.event.pull_request.base.sha }}" >> $GITHUB_ENV + echo "HEAD_SHA=${{ github.event.pull_request.head.sha }}" >> $GITHUB_ENV + + + - name: Run Gitleaks on PR changes via Docker + run: | + docker run --rm -v $(pwd):/repo -w /repo zricethezav/gitleaks:latest detect \ + --config="/repo/Rule/gitleaks.toml" \ + --log-opts="--no-merges $BASE_SHA..$HEAD_SHA" \ + --verbose \ + --exit-code=0 \ + --report-format=json \ + --report-path="/repo/gitleaks-report.json" \ + --redact + + - name: Upload Gitleaks report + uses: actions/upload-artifact@v4 + with: + name: gitleaks-report + path: gitleaks-report.json + + - name: Format and comment findings on PR + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: | + if [ ! -f gitleaks-report.json ]; then + echo "Report file not found!" + exit 1 + fi + + FINDINGS_JSON=$(cat gitleaks-report.json) + COUNT=$(echo "$FINDINGS_JSON" | jq 'length') + SHA="${{ github.event.pull_request.head.sha }}" + REPO="${{ github.repository }}" + PR_NUMBER="${{ github.event.pull_request.number }}" + MAX=10 + + if [ "$COUNT" -gt 0 ]; then + COMMENT="**🔐 Gitleaks Findings: $COUNT issue(s) detected**\n\n" + i=0 + while [ "$i" -lt "$COUNT" ] && [ "$i" -lt "$MAX" ]; do + ITEM=$(echo "$FINDINGS_JSON" | jq ".[$i]") + RULE=$(echo "$ITEM" | jq -r '.RuleID') + DESC=$(echo "$ITEM" | jq -r '.Description') + FILE=$(echo "$ITEM" | jq -r '.File') + LINE=$(echo "$ITEM" | jq -r '.Line') + LINK="https://github.com/$REPO/blob/$SHA/$FILE#L$LINE" + SECRET_MASKED="**********" + COMMENT+="🔸 **Rule**: \`$RULE\`\n" + COMMENT+="📄 **File**: \`$FILE:$LINE\`\n" + COMMENT+="📝 **Description**: $DESC\n" + COMMENT+="🔑 **Secret**: \`$SECRET_MASKED\`\n" + COMMENT+="🔗 **Path**: [$FILE:$LINE]($LINK)\n\n" + i=$((i + 1)) + done + + if [ "$COUNT" -gt "$MAX" ]; then + COMMENT+="...and more. Only showing first $MAX findings.\n" + fi + else + COMMENT="✅ **Gitleaks Findings:** No secrets detected. Safe to proceed!" + fi + + # Escape newlines for GitHub API + COMMENT=$(echo "$COMMENT" | sed ':a;N;$!ba;s/\n/\\n/g') + + curl -X POST \ + -H "Authorization: token $GITHUB_TOKEN" \ + -H "Accept: application/vnd.github.v3+json" \ + -d "{\"body\":\"$COMMENT\"}" \ + "https://api.github.com/repos/${REPO}/issues/${PR_NUMBER}/comments" diff --git a/.github/workflows/semgrep.yml b/.github/workflows/semgrep.yml index bce5fc8e..019095aa 100644 --- a/.github/workflows/semgrep.yml +++ b/.github/workflows/semgrep.yml @@ -1,35 +1,64 @@ -name: Semgrep +name: Semgrep Scan -# Run workflow each time code is pushed to your repository. on: - push: - branches: - - main pull_request: branches: - main + jobs: build: runs-on: ubuntu-latest + permissions: + pull-requests: write # Give write permission to PRs + issues: write steps: - name: Checkout code uses: actions/checkout@v3 - - name: Install Semgrep - run: pip install semgrep + - name: Install Semgrep and jq + run: | + sudo apt install python3-venv jq + python3 -m venv .venv + .venv/bin/pip install semgrep - name: Run Semgrep run: | - semgrep --config .semgreprules/customRule.yml --config auto --severity ERROR --sarif . > results.sarif + source .venv/bin/activate + semgrep --config auto --severity ERROR --json-output=results.json --no-error + cat results.json | jq .results > pretty-results.json - - name: Upload SARIF file - uses: github/codeql-action/upload-sarif@v3 + - name: Display Raw Semgrep JSON Output + run: | + echo "Displaying raw Semgrep results..." + cat pretty-results.json + + - name: Add comment on PR if findings are found + uses: actions/github-script@v6 with: - # Path to SARIF file relative to the root of the repository - sarif_file: results.sarif + script: | + // Ensure the context has a pull_request + if (context.payload.pull_request) { + const prNumber = context.payload.pull_request.number; + const fs = require('fs'); + const results = JSON.parse(fs.readFileSync('pretty-results.json', 'utf8')); + const highFindings = results.filter(result => result.extra && result.extra.severity === 'ERROR'); - - name: Upload results - uses: actions/upload-artifact@v4 - with: - name: semgrep-results - path: results.sarif + // Comment if findings exist + if (highFindings.length > 0) { + const comment = `**Semgrep Findings:** Issues with Error level severity are found (Error is Highest severity in Semgrep), Please resolve the issues before merging.`; + await github.rest.issues.createComment({ + ...context.repo, + issue_number: prNumber, + body: comment + }); + } else { + const noIssuesComment = "**Semgrep findings:** No issues found, Good to merge."; + await github.rest.issues.createComment({ + ...context.repo, + issue_number: prNumber, + body: noIssuesComment + }); + } + } else { + console.log("This workflow wasn't triggered by a pull request, so no comment will be added."); + } diff --git a/.semgreprules/customRule.yml b/.semgreprules/customRule.yml deleted file mode 100644 index b275e280..00000000 --- a/.semgreprules/customRule.yml +++ /dev/null @@ -1,30 +0,0 @@ -rules: -- id: check-sensitive-info - message: >- - Potential sensitive information found: $1 - severity: ERROR - languages: - - yaml - - go - - javascript - - java - - python - - golang - - docker - patterns: - - pattern-regex: (?i)\b(api[_-]key|api[_-]token|api[_-]secret[_-]key|api[_-]password|token|secret[_-]key|password|auth[_-]key|auth[_-]token|AUTH_PASSWORD)\s*[:=]\s*(['"]?)((?!YOUR_EXCLUSION_PATTERN_HERE)[A-Z]+.*?)\2 - -- id: check-logger-appconfig - message: >- - Potential Logging configuration found: $1 - severity: ERROR - languages: - - yaml - - go - - javascript - - java - - python - - golang - - docker - patterns: - - pattern-regex: log\.Logger\(\).*(appConfig).* diff --git a/README.md b/README.md index 7c80d174..a5bd66c8 100644 --- a/README.md +++ b/README.md @@ -15,35 +15,12 @@ The Skyflow Java SDK is designed to help with integrating Skyflow into a Java ba - [Configuration](#configuration) - [Gradle users](#gradle-users) - [Maven users](#maven-users) -- [Migration from v1 to v2](#migration-from-v1-to-v2) - - [Authentication options](#authentication-options) - - [Initializing the client](#initializing-the-client) - - [Request & response structure](#request--response-structure) - - [Request options](#request-options) - - [Error structure](#error-structure) - [Quickstart](#quickstart) - [Authenticate](#authenticate) - [Initialize the client](#initialize-the-client) - - [Insert data into the vault](#insert-data-into-the-vault) - [Vault](#vault) - - [Insert data into the vault](#insert-data-into-the-vault-1) - - [Detokenize](#detokenize) - - [Tokenize](#tokenize) - - [Get](#get) - - [Get by skyflow IDS](#get-by-skyflow-ids) - - [Get tokens](#get-tokens) - - [Get by column name and column values](#get-by-column-name-and-column-values) - - [Redaction types](#redaction-types) - - [Update](#update) - - [Delete](#delete) - - [Query](#query) -- [Detect](#detect) - - [Deidentify Text](#deidentify-text) - - [Reidentify Text](#reidentify-text) - - [Deidentify File](#deidentify-file) - - [Get Run](#get-run) -- [Connections](#connections) - - [Invoke a connection](#invoke-a-connection) + - [Bulk insert data into the vault](#bulk-insert-data-into-the-vault) + - [Bulk Detokenize](#bulk-detokenize) - [Authenticate with bearer tokens](#authenticate-with-bearer-tokens) - [Generate a bearer token](#generate-a-bearer-token) - [Generate bearer tokens with context](#generate-bearer-tokens-with-context) @@ -56,8 +33,7 @@ The Skyflow Java SDK is designed to help with integrating Skyflow into a Java ba # Overview - Authenticate using a Skyflow service account and generate bearer tokens for secure access. -- Perform Vault API operations such as inserting, retrieving, and tokenizing sensitive data with ease. -- Invoke connections to third-party APIs without directly handling sensitive data, ensuring compliance and data protection. +- Perform Vault API operations such as inserting, and detokenizing sensitive data with ease. # Install @@ -74,7 +50,7 @@ The Skyflow Java SDK is designed to help with integrating Skyflow into a Java ba Add this dependency to your project's `build.gradle` file: ``` -implementation 'com.skyflow:skyflow-java:2.0.0' +implementation 'com.skyflow:skyflow-java:3.0.0-beta.3' ``` ### Maven users @@ -85,277 +61,15 @@ Add this dependency to your project's `pom.xml` file: com.skyflow skyflow-java - 2.0.0 + 3.0.0-beta.3 ``` --- -# Migrate from v1 to v2 - -Below are the steps to migrate the java sdk from v1 to v2. - -### Authentication options - -In V2, we have introduced multiple authentication options. You can now provide credentials in the following ways: - -- Passing credentials in ENV. (`SKYFLOW_CREDENTIALS`) _(Recommended)_ -- API Key -- Path to your credentials JSON file -- Stringified JSON of your credentials -- Bearer token - -These options allow you to choose the authentication method that best suits your use case. - -**V1 (Old)** - -```java -static class DemoTokenProvider implements TokenProvider { - @Override - public String getBearerToken() throws Exception { - ResponseToken res = null; - try { - String filePath = ""; - res = Token.generateBearerToken(filePath); - } catch (SkyflowException e) { - e.printStackTrace(); - } - return res.getAccessToken(); - } -} -``` - -**V2 (New): Passing one of the following:** - -```java -// Option 1: API Key (Recommended) -Credentials skyflowCredentials = new Credentials(); -skyflowCredentials.setApiKey(""); // Replace with your actual API key - -// Option 2: Environment Variables (Recommended) -// Set SKYFLOW_CREDENTIALS in your environment - -// Option 3: Credentials File -skyflowCredentials.setPath(""); // Replace with the path to credentials file - -// Option 4: Stringified JSON -skyflowCredentials.setCredentialsString(""); // Replace with the credentials string - -// Option 5: Bearer Token -skyflowCredentials.setToken(""); // Replace with your actual authentication token. -``` - -Notes: - -- Use only ONE authentication method. -- API Key or environment variables are recommended for production use. -- Secure storage of credentials is essential. -- For overriding behavior and priority order of credentials, please refer to [Initialize the client](#initialize-the-client) section in [Quickstart](#quickstart). - ---- - -### Initializing the client - -In V2, we have introduced a builder design pattern for client initialization and added support for multi-vault. This allows you to configure multiple vaults during client initialization. In V2, the log level is tied to each individual client instance. During client initialization, you can pass the following parameters: - -- `vaultId` and `clusterId`: These values are derived from the vault ID & vault URL. -- `env`: Specify the environment (e.g., SANDBOX or PROD). -- `credentials`: The necessary authentication credentials. - -**V1 (Old)** - -```java -// DemoTokenProvider class is an implementation of the TokenProvider interface -DemoTokenProvider demoTokenProvider = new DemoTokenProvider(); -SkyflowConfiguration skyflowConfig = new SkyflowConfiguration("","", demoTokenProvider); -Skyflow skyflowClient = Skyflow.init(skyflowConfig); -``` - -**V2 (New)** - -```java -Credentials credentials = new Credentials(); -credentials.setPath(""); // Replace with the path to the credentials file - -// Configure the first vault (Blitz) -VaultConfig config = new VaultConfig(); -config.setVaultId(""); // Replace with the ID of the first vault -config.setClusterId(""); // Replace with the cluster ID of the first vault -config.setEnv(Env.DEV); // Set the environment (e.g., DEV, STAGE, PROD) -config.setCredentials(credentials); // Associate the credentials with the vault - -// Set up credentials for the Skyflow client -Credentials skyflowCredentials = new Credentials(); -skyflowCredentials.setPath(""); // Replace with the path to another credentials file - -// Create a Skyflow client and add vault configurations -Skyflow skyflowClient = Skyflow.builder() - .setLogLevel(LogLevel.DEBUG) // Enable debugging for detailed logs - .addVaultConfig(config) // Add the first vault configuration - .addSkyflowCredentials(skyflowCredentials) // Add general Skyflow credentials - .build(); -``` - -**Key Changes:** - -- `vaultUrl` replaced with `clusterId`. -- Added environment specification (`env`). -- Instance-specific log levels. - ---- - -### Request & response structure - -In V2, we have removed the use of JSON objects from a third-party package. Instead, we have transitioned to accepting native ArrayList and HashMap data structures and adopted the builder pattern for request creation. This request needs: - -- `table`: The name of the table. -- `values`: An array list of objects containing the data to be inserted. - -The response will be of type `InsertResponse` class, which contains `insertedFields` and `errors`. - -**V1 (Old):** Request building - -```java -JSONObject recordsJson = new JSONObject(); -JSONArray recordsArrayJson = new JSONArray(); - -JSONObject recordJson = new JSONObject(); -recordJson.put("table", "cards"); - -JSONObject fieldsJson = new JSONObject(); -fields.put("cardNumber", "41111111111"); -fields.put("cvv", "123"); - -recordJson.put("fields", fieldsJson); -recordsArrayJson.add(record); -recordsJson.put("records", recordsArrayJson); -try { - JSONObject insertResponse = skyflowClient.insert(records); - System.out.println(insertResponse); -} catch (SkyflowException exception) { - System.out.println(exception); -} -``` - -**V2 (New):** Request building - -```java -ArrayList> values = new ArrayList<>(); -HashMap value = new HashMap<>(); -value.put("", ""); // Replace with column name and value -value.put("", ""); // Replace with another column name and value -values.add(values); - -ArrayList> tokens = new ArrayList<>(); -HashMap token = new HashMap<>(); -token.put("", ""); // Replace with the token for COLUMN_NAME_2 -tokens.add(token); - -InsertRequest insertRequest = InsertRequest.builder() - .table("") // Replace with the table name - .continueOnError(true) // Continue inserting even if some records fail - .tokenMode(TokenMode.ENABLE) // Enable BYOT for token validation - .values(values) // Data to insert - .tokens(tokens) // Provide tokens for BYOT columns - .returnTokens(true) // Return tokens along with the response - .build(); -``` - -**V1 (Old):** Response structure - -```json -{ - "records": [ - { - "table": "cards", - "fields": { - "skyflow_id": "16419435-aa63-4823-aae7-19c6a2d6a19f", - "cardNumber": "f3907186-e7e2-466f-91e5-48e12c2bcbc1", - "cvv": "1989cb56-63da-4482-a2df-1f74cd0dd1a5" - } - } - ] -} -``` - -**V2 (New):** Response structure - -```json -{ - "insertedFields": [ - { - "card_number": "5484-7829-1702-9110", - "request_index": "0", - "skyflow_id": "9fac9201-7b8a-4446-93f8-5244e1213bd1", - "cardholder_name": "b2308e2a-c1f5-469b-97b7-1f193159399b" - } - ], - "errors": [] -} -``` - ---- - -### Request options - -In V2, with the introduction of the builder design pattern has made handling optional fields in Java more efficient and straightforward. - -**V1 (Old)** - -```java -InsertOptions insertOptions = new InsertOptions(true); -``` - -**V2 (New)** - -```java -InsertRequest upsertRequest = new InsertRequest.builder() - .table("") // Replace with the table name - .continueOnError(false) // Stop inserting if any record fails - .tokenMode(TokenMode.DISABLE) // Disable BYOT - .values(values) // Data to insert - .returnTokens(false) // Do not return tokens - .upsert("") // Replace with the column name used for upsert logic - .build(); -``` - ---- - -### Error structure - -In V2, we have enriched the error details to provide better debugging capabilities. -The error response now includes: - -- `httpStatus`: The HTTP status code. -- `grpcCode`: The gRPC code associated with the error. -- `details` & `message`: A detailed description of the error. -- `requestId`: A unique request identifier for easier debugging. - -**V1 (Old):** Error structure - -```json -{ - "code": "", - "description": "" -} -``` - -**V2 (New):** Error structure - -```js -{ - "httpStatus": "", - "grpcCode": , - "httpCode": , - "message": "", - "requestId": "", - "details": ["
"] -} -``` - # Quickstart -Get started quickly with the essential steps: authenticate, initialize the client, and perform a basic vault operation. This section provides a minimal setup to help you integrate the SDK efficiently. +Get started quickly with the essential steps: authenticate and initialize the client. This section provides a minimal setup to help you integrate the SDK efficiently. ### Authenticate @@ -394,7 +108,7 @@ import com.skyflow.enums.LogLevel; import com.skyflow.errors.SkyflowException; /** - * Example program to initialize the Skyflow client with various configurations. + * Example program to initialize the Skyflow client with a vault configuration. * The Skyflow client facilitates secure interactions with the Skyflow vault, * such as securely managing sensitive data. */ @@ -408,16 +122,16 @@ public class InitSkyflowClient { // - A file path to a credentials file. // Initialize primary credentials using a Bearer token for authentication. - Credentials primaryCredentials = new Credentials(); - primaryCredentials.setToken(""); // Replace with your actual authentication token. + Credentials credentials = new Credentials(); + credentials.setToken(""); // Replace with your actual authentication token. // Step 2: Configure the primary vault details. // VaultConfig stores all necessary details to connect to a specific Skyflow vault. - VaultConfig primaryConfig = new VaultConfig(); - primaryConfig.setVaultId(""); // Replace with your primary vault's ID. + VaultConfig config = new VaultConfig(); + primaryConfig.setVaultId(""); // Replace with your vault's ID. primaryConfig.setClusterId(""); // Replace with the cluster ID (part of the vault URL, e.g., https://{clusterId}.vault.skyflowapis.com). primaryConfig.setEnv(Env.PROD); // Set the environment (PROD, SANDBOX, STAGE, DEV). - primaryConfig.setCredentials(primaryCredentials); // Attach the primary credentials to this vault configuration. + primaryConfig.setCredentials(credentials); // Attach the credentials to this vault configuration. // Step 3: Create credentials as a JSON object (if a Bearer Token is not provided). // Demonstrates an alternate approach to authenticate with Skyflow using a credentials object. @@ -433,46 +147,18 @@ public class InitSkyflowClient { Credentials skyflowCredentials = new Credentials(); skyflowCredentials.setCredentialsString(credentialsObject.toString()); // Converts JSON object to string for use as credentials. - // Step 5: Define secondary credentials (API key-based authentication as an example). - // Demonstrates a different type of authentication mechanism for Skyflow vaults. - Credentials secondaryCredentials = new Credentials(); - secondaryCredentials.setApiKey(""); // Replace with your API Key for authentication. - - // Step 6: Configure the secondary vault details. - // A secondary vault configuration can be used for operations involving multiple vaults. - VaultConfig secondaryConfig = new VaultConfig(); - secondaryConfig.setVaultId(""); // Replace with your secondary vault's ID. - secondaryConfig.setClusterId(""); // Replace with the corresponding cluster ID. - secondaryConfig.setEnv(Env.SANDBOX); // Set the environment for this vault. - secondaryConfig.setCredentials(secondaryCredentials); // Attach the secondary credentials to this configuration. - - // Step 7: Define tertiary credentials using a path to a credentials JSON file. - // This method demonstrates an alternative authentication method. - Credentials tertiaryCredentials = new Credentials(); - tertiaryCredentials.setPath(""); // Replace with the path to your credentials file. - - // Step 8: Configure the tertiary vault details. - VaultConfig tertiaryConfig = new VaultConfig(); - tertiaryConfig.setVaultId(""); // Replace with the tertiary vault ID. - tertiaryConfig.setClusterId(""); // Replace with the corresponding cluster ID. - tertiaryConfig.setEnv(Env.STAGE); // Set the environment for this vault. - tertiaryConfig.setCredentials(tertiaryCredentials); // Attach the tertiary credentials. - - // Step 9: Build and initialize the Skyflow client. + // Step 5: Build and initialize the Skyflow client. // Skyflow client is configured with multiple vaults and credentials. Skyflow skyflowClient = Skyflow.builder() .setLogLevel(LogLevel.INFO) // Set log level for debugging or monitoring purposes. - .addVaultConfig(primaryConfig) // Add the primary vault configuration. - .addVaultConfig(secondaryConfig) // Add the secondary vault configuration. - .addVaultConfig(tertiaryConfig) // Add the tertiary vault configuration. + .addVaultConfig(config) // Add the vault configuration. .addSkyflowCredentials(skyflowCredentials) // Add JSON-formatted credentials if applicable. .build(); // The Skyflow client is now fully initialized. // Use the `skyflowClient` object to perform secure operations such as: // - Inserting data - // - Retrieving data - // - Deleting data + // - Detokenizing data // within the configured Skyflow vaults. } } @@ -484,86 +170,13 @@ Notes: - If neither Skyflow common credentials nor individual configuration-level credentials are provided, the SDK attempts to retrieve credentials from the `SKYFLOW_CREDENTIALS` environment variable. - All Vault operations require a client instance. -### Insert data into the vault - -To insert data into your vault, use the `insert` method. The `InsertRequest` class creates an insert request, which includes the values to be inserted as a list of records. Below is a simple example to get started. For advanced options, check out [Insert data into the vault](#insert-data-into-the-vault-1) section. - -```java -import com.skyflow.errors.SkyflowException; -import com.skyflow.vault.data.InsertRequest; -import com.skyflow.vault.data.InsertResponse; - -import java.util.ArrayList; -import java.util.HashMap; - -/** - * This example demonstrates how to insert sensitive data (e.g., card information) into a Skyflow vault using the Skyflow client. - * - * 1. Initializes the Skyflow client. - * 2. Prepares a record with sensitive data (e.g., card number and cardholder name). - * 3. Creates an insert request for inserting the data into the Skyflow vault. - * 4. Prints the response of the insert operation. - */ -public class InsertExample { - public static void main(String[] args) { - try { - // Initialize Skyflow client - // Step 1: Initialize data to be inserted into the Skyflow vault - ArrayList> insertData = new ArrayList<>(); - - // Create a HashMap for a single record with card number and cardholder name as fields - HashMap insertRecord = new HashMap<>(); - insertRecord.put("card_number", "4111111111111111"); // Replace with actual card number (sensitive data) - insertRecord.put("cardholder_name", "john doe"); // Replace with actual cardholder name (sensitive data) - - // Add the created record to the list of data to be inserted - insertData.add(insertRecord); - - // Step 2: Build the InsertRequest object with the table name and data to insert - InsertRequest insertRequest = InsertRequest.builder() - .table("table1") // Specify the table in the vault where the data will be inserted - .values(insertData) // Attach the data (records) to be inserted - .returnTokens(true) // Specify if tokens should be returned upon successful insertion - .build(); // Build the insert request object - - // Step 3: Perform the insert operation using the Skyflow client - InsertResponse insertResponse = skyflowClient.vault("9f27764a10f7946fe56b3258e117").insert(insertRequest); - // Replace the vault ID "9f27764a10f7946fe56b3258e117" with your actual Skyflow vault ID - - // Step 4: Print the response from the insert operation - System.out.println(insertResponse); - } catch (SkyflowException e) { - // Step 5: Handle any exceptions that may occur during the insert operation - System.out.println("Error occurred: "); - e.printStackTrace(); // Print the stack trace for debugging purposes - } - } -} -``` - -Skyflow returns tokens for the record that was just inserted. - -```json -{ - "insertedFields": [ - { - "card_number": "5484-7829-1702-9110", - "request_index": "0", - "skyflow_id": "9fac9201-7b8a-4446-93f8-5244e1213bd1", - "cardholder_name": "b2308e2a-c1f5-469b-97b7-1f193159399b" - } - ], - "errors": [] -} -``` - # Vault -The [Vault](https://github.com/skyflowapi/skyflow-java/tree/main/src/main/java/com/skyflow/vault) module performs operations on the vault, including inserting records, detokenizing tokens, and retrieving tokens associated with a `skyflow_id`. +The [Vault](https://github.com/skyflowapi/skyflow-java/tree/main/src/main/java/com/skyflow/vault) module performs operations on the vault, including inserting records and detokenizing tokens. -## Insert data into the vault +## Bulk insert data into the vault -Apart from using the `insert` method to insert data into your vault covered in [Quickstart](#quickstart), you can also specify options in `InsertRequest`, such as returning tokenized data, upserting records, or continuing the operation in case of errors. +To insert data into your vault, use the `bulkinsert` or `bulkInsertAsync` methods. The `InsertRequest` class creates an insert request, which includes the values to be inserted as a list of records. ### Construct an insert request @@ -582,7 +195,8 @@ import java.util.HashMap; public class InsertSchema { public static void main(String[] args) { try { - // Initialize Skyflow client + // Initialize Skyflow client + // Step 1: Prepare the data to be inserted into the Skyflow vault ArrayList> insertData = new ArrayList<>(); @@ -606,9 +220,8 @@ public class InsertSchema { .values(insertData) // Attach the data to be inserted .build(); - // Step 3: Use the Skyflow client to perform the insert operation - InsertResponse insertResponse = skyflowClient.vault("").insert(insertRequest); - // Replace with your actual vault ID + // Step 3: Use the Skyflow client to perform the sync bulk insert operation + InsertResponse insertResponse = skyflowClient.vault().bulkInsert(insertRequest); // Print the response from the insert operation System.out.println("Insert Response: " + insertResponse); @@ -621,95 +234,107 @@ public class InsertSchema { } ``` -### Insert call [example](https://github.com/skyflowapi/skyflow-java/blob/SK-1893-update-readme-for-v2/samples/src/main/java/com/example/vault/InsertExample.java) with `continueOnError` option +### An [example](https://github.com/skyflowapi/skyflow-java/blob/v3/samples/src/main/java/com/example/vault/BulkInsertSync.java) of a sync bulkInsert call -The `continueOnError` flag is a boolean that determines whether insert operation should proceed despite encountering partial errors. Set to `true` to allow the process to continue even if some errors occur. +The `bulkInsert` operation operation will insert the data synchronously into the vault. ```java -import com.skyflow.errors.SkyflowException; -import com.skyflow.vault.data.InsertRequest; -import com.skyflow.vault.data.InsertResponse; - -import java.util.ArrayList; -import java.util.HashMap; - /** - * This example demonstrates how to insert multiple records into a Skyflow vault using the Skyflow client. - * - * 1. Initializes the Skyflow client. - * 2. Prepares multiple records with sensitive data (e.g., card number and cardholder name). - * 3. Creates an insert request with the records to insert into the Skyflow vault. - * 4. Specifies options to continue on error and return tokens. - * 5. Prints the response of the insert operation. + * Example program to demonstrate how to perform a synchronous bulk insert operation using the Skyflow Java SDK. + * The process involves: + * 1. Setting up credentials and vault configuration + * 2. Creating multiple records to be inserted + * 3. Building and executing a bulk insert request + * 4. Handling the insert response or any potential errors */ -public class InsertExample { +public class BulkInsertSync { public static void main(String[] args) { try { - // Initialize Skyflow client - // Step 1: Initialize a list to hold the data records to be inserted into the vault + // Initialize Skyflow client + + // Step 1: Prepare the data to be inserted into the Skyflow vault ArrayList> insertData = new ArrayList<>(); - // Step 2: Create the first record with card number and cardholder name + // Create the first record with field names and their respective values HashMap insertRecord1 = new HashMap<>(); - insertRecord1.put("card_number", "4111111111111111"); // Replace with actual card number (sensitive data) - insertRecord1.put("cardholder_name", "john doe"); // Replace with actual cardholder name (sensitive data) + insertRecord1.put("name", "John doe"); // Replace with actual field name and value + insertRecord1.put("email", "john.doe@example.com"); // Replace with actual field name and value - // Step 3: Create the second record with card number and cardholder name + // Create the second record with field names and their respective values HashMap insertRecord2 = new HashMap<>(); - insertRecord2.put("card_number", "4111111111111111"); // Ensure field name matches ("card_number") - insertRecord2.put("cardholder_name", "jane doe"); // Replace with actual cardholder name (sensitive data) + insertRecord2.put("name", "Jane doe"); // Replace with actual field name and value + insertRecord2.put("email", "jane.doe@example.com"); // Replace with actual field name and value - // Step 4: Add the records to the insertData list + // Add the records to the list of data to be inserted insertData.add(insertRecord1); insertData.add(insertRecord2); - // Step 5: Build the InsertRequest object with the data records to insert + // Step 2: Build an InsertRequest object with the table name and the data to insert InsertRequest insertRequest = InsertRequest.builder() - .table("table1") // Specify the table in the vault where data will be inserted - .values(insertData) // Attach the data records to be inserted - .returnTokens(true) // Specify if tokens should be returned upon successful insertion - .continueOnError(true) // Specify to continue inserting records even if an error occurs for some records - .build(); // Build the insert request object - - // Step 6: Perform the insert operation using the Skyflow client - InsertResponse insertResponse = skyflowClient.vault("9f27764a10f7946fe56b3258e117").insert(insertRequest); - // Replace the vault ID "9f27764a10f7946fe56b3258e117" with your actual Skyflow vault ID - - // Step 7: Print the response from the insert operation - System.out.println(insertResponse); + .table("table1") // Replace with the actual table name in your Skyflow vault + .values(insertData) // Attach the data to be inserted + .build(); + + // Step 3: Use the Skyflow client to perform the sync bulk insert operation + InsertResponse insertResponse = skyflowClient.vault().bulkInsert(insertRequest); + + // Print the response from the insert operation + System.out.println("Insert Response: " + insertResponse); } catch (SkyflowException e) { - // Step 8: Handle any exceptions that may occur during the insert operation - System.out.println("Error occurred: "); - e.printStackTrace(); // Print the stack trace for debugging purposes + // Step 4: Handle any exceptions that occur during the insert operation + System.out.println("Error occurred while inserting data: "); + e.printStackTrace(); // Print the stack trace for debugging } } } ``` -Sample response: +Skyflow returns tokens and data for the records that were just inserted. ```json { - "insertedFields": [ + "summary": { + "totalRecords": 2, + "totalInserted": 2, + "totalFailed": 0 + }, + "sucess": [ { - "card_number": "5484-7829-1702-9110", - "request_index": "0", + "index": 0, "skyflow_id": "9fac9201-7b8a-4446-93f8-5244e1213bd1", - "cardholder_name": "b2308e2a-c1f5-469b-97b7-1f193159399b" - } - ], - "errors": [ + "tokens": { + "name": [{ "token": "token_name", "tokenGroupName": "deterministic_string" }], + "email": [ + { + "token": "augn0@xebggri.lmp", + "tokenGroupName": "nondeterministic_string" + } + ] + }, + "data": { "email": "john.doe@example.com", "name": "john doe" } + }, { - "request_index": "1", - "error": "Insert failed. Column card_numbe is invalid. Specify a valid column." - } - ] + "index": 1, + "skyflow_id": "9fac9201-7b8a-4446-93f8-5244e1213bd3", + "tokens": { + "name": [{ "token": "token_name", "tokenGroupName": "deterministic_string" }], + "email": [ + { + "token": "buhn0@xebggrj.lmt", + "tokenGroupName": "nondeterministic_string" + } + ] + }, + "data": { "email": "jane.doe@example.com", "name": "Jane doe" } + }, + ], + "errors": [] } ``` -### Insert call example with `upsert` option +### An [example](https://github.com/skyflowapi/skyflow-java/blob/v3/samples/src/main/java/com/example/vault/BulkInsertAsync.java) of an async bulkInsert call -An upsert operation checks for a record based on a unique column's value. If a match exists, the record is updated; otherwise, a new record is inserted. +The `bulkInsertAsync` operation operation will insert the data asynchronously into the vault. ```java import com.skyflow.errors.SkyflowException; @@ -720,42 +345,49 @@ import java.util.ArrayList; import java.util.HashMap; /** - * This example demonstrates how to insert or upsert a record into a Skyflow vault using the Skyflow client, with the option to return tokens. - * - * 1. Initializes the Skyflow client. - * 2. Prepares a record to insert or upsert (e.g., cardholder name). - * 3. Creates an insert request with the data to be inserted or upserted into the Skyflow vault. - * 4. Specifies the field (cardholder_name) for upsert operations. - * 5. Prints the response of the insert or upsert operation. + * Example program to demonstrate how to perform an asynchronous bulk insert operation using the Skyflow Java SDK. + * The process involves: + * 1. Setting up credentials and vault configuration + * 2. Creating multiple records to be inserted + * 3. Building and executing an async bulk insert request + * 4. Handling the insert response or errors using CompletableFuture */ -public class UpsertExample { +public class BulkInsertAsync { public static void main(String[] args) { try { // Initialize Skyflow client - // Step 1: Initialize a list to hold the data records for the insert/upsert operation - ArrayList> upsertData = new ArrayList<>(); + // Step 1: Prepare the data to be inserted into the Skyflow vault + ArrayList> insertData = new ArrayList<>(); + + // Create the first record with field names and their respective values + HashMap insertRecord1 = new HashMap<>(); + insertRecord1.put("name", "John doe"); // Replace with actual field name and value + insertRecord1.put("email", "john.doe@example.com"); // Replace with actual field name and value - // Step 2: Create a record with the field 'cardholder_name' to insert or upsert - HashMap upsertRecord = new HashMap<>(); - upsertRecord.put("cardholder_name", "jane doe"); // Replace with the actual cardholder name + // Create the second record with field names and their respective values + HashMap insertRecord2 = new HashMap<>(); + insertRecord2.put("name", "Jane doe"); // Replace with actual field name and value + insertRecord2.put("email", "jane.doe@example.com"); // Replace with actual field name and value - // Step 3: Add the record to the upsertData list - upsertData.add(upsertRecord); + // Add the records to the list of data to be inserted + insertData.add(insertRecord1); + insertData.add(insertRecord2); - // Step 4: Build the InsertRequest object with the upsertData + // Step 2: Build an InsertRequest object with the table name and the data to insert InsertRequest insertRequest = InsertRequest.builder() - .table("table1") // Specify the table in the vault where data will be inserted/upserted - .values(upsertData) // Attach the data records to be inserted/upserted - .returnTokens(true) // Specify if tokens should be returned upon successful operation - .upsert("cardholder_name") // Specify the field to be used for upsert operations (e.g., cardholder_name) - .build(); // Build the insert request object - - // Step 5: Perform the insert/upsert operation using the Skyflow client - InsertResponse insertResponse = skyflowClient.vault("9f27764a10f7946fe56b3258e117").insert(insertRequest); - // Replace the vault ID "9f27764a10f7946fe56b3258e117" with your actual Skyflow vault ID - - // Step 6: Print the response from the insert/upsert operation - System.out.println(insertResponse); + .table("table1") // Replace with the actual table name in your Skyflow vault + .values(insertData) // Attach the data to be inserted + .build(); + + // Step 3: Perform the async bulk insert operation using the Skyflow client + CompletableFuture future = skyflowClient.vault().bulkInsertAsync(insertRequest); + // Add success and error callbacks + future.thenAccept(response -> { + System.out.println("Async bulk insert resolved with response:\t" + response); + }).exceptionally(throwable -> { + System.err.println("Async bulk insert rejected with error:\t" + throwable.getMessage()); + throw new CompletionException(throwable); + }); } catch (SkyflowException e) { // Step 7: Handle any exceptions that may occur during the insert/upsert operation System.out.println("Error occurred: "); @@ -765,23 +397,55 @@ public class UpsertExample { } ``` -Skyflow returns tokens, with `upsert` support, for the record you just inserted. +Skyflow returns tokens and data for the records you just inserted. ```json { - "insertedFields": [ + "summary": { + "totalRecords": 2, + "totalInserted": 2, + "totalFailed": 0 + }, + "sucess": [ { - "skyflowId": "9fac9201-7b8a-4446-93f8-5244e1213bd1", - "cardholder_name": "73ce45ce-20fd-490e-9310-c1d4f603ee83" - } + "index": 0, + "skyflow_id": "9fac9201-7b8a-4446-93f8-5244e1213bd1", + "tokens": { + "name": [{ "token": "token_name", "tokenGroupName": "deterministic_string" }], + "email": [ + { + "token": "augn0@xebggri.lmp", + "tokenGroupName": "nondeterministic_string" + } + ] + }, + "data": { "email": "john.doe@example.com", "name": "john doe" } + }, + { + "index": 1, + "skyflow_id": "9fac9201-7b8a-4446-93f8-5244e1213bd3", + "tokens": { + "name": [{ "token": "token_name", "tokenGroupName": "deterministic_string" }], + "email": [ + { + "token": "buhn0@xebggrj.lmt", + "tokenGroupName": "nondeterministic_string" + } + ] + }, + "data": { "email": "jane.doe@example.com", "name": "Jane doe" } + }, ], "errors": [] } ``` -## Detokenize +## Bulk detokenize + +To retrieve tokens from your vault, use the `bulkDetokenize` or `bulkDetokenizeAsync` methods. You can specify how the data should be redacted based on token groups. The `DetokenizeRequest` has two main components: -To retrieve tokens from your vault, use the `detokenize` method. The `DetokenizeRequest` class requires a list of detokenization data as input. Additionally, you can provide optional parameters, such as the redaction type and the option to continue on error. +- `tokens`: List of token strings to detokenize +- `tokenGroupRedactions`: List of redaction rules for specific token groups ### Construct a detokenize request @@ -800,23 +464,28 @@ import java.util.ArrayList; public class DetokenizeSchema { public static void main(String[] args) { try { - // Initialize Skyflow client + // Initialize Skyflow client // Step 1: Initialize a list of tokens to be detokenized (replace with actual tokens) ArrayList tokens = new ArrayList<>(); tokens.add(""); // Replace with your actual token value tokens.add(""); // Replace with your actual token value tokens.add(""); // Replace with your actual token value - // Step 2: Create the DetokenizeRequest object with the tokens and redaction type + TokenGroupRedactions tokenGroupRedaction = TokenGroupRedactions.builder() + .tokenGroupName("") + .redaction("") + .build(); + List tokenGroupRedactions = new ArrayList<>(); + tokenGroupRedactions.add(tokenGroupRedaction); + + // Step 2: Create the DetokenizeRequest object with the tokens and token group redactions DetokenizeRequest detokenizeRequest = DetokenizeRequest.builder() - .tokens(tokens) // Provide the list of tokens to be detokenized - .continueOnError(true) // Continue even if one token cannot be detokenized - .redactionType(RedactionType.PLAIN_TEXT) // Specify how the detokenized data should be returned (plain text) - .build(); // Build the detokenization request + .tokens(tokens) // Provide the list of tokens to be detokenized + .tokenGroupredactions(tokenGroupRedactions) // Provide a list of token grpup redactions + .build(); // Build the detokenization request // Step 3: Call the Skyflow vault to detokenize the provided tokens - DetokenizeResponse detokenizeResponse = skyflowClient.vault("").detokenize(detokenizeRequest); - // Replace with your actual Skyflow vault ID + DetokenizeResponse detokenizeResponse = skyflowClient.vault().bulkDetokenize(detokenizeRequest); // Step 4: Print the detokenization response, which contains the detokenized data System.out.println(detokenizeResponse); @@ -829,50 +498,50 @@ public class DetokenizeSchema { } ``` -Notes: - -- `redactionType` defaults to [`RedactionType.PLAIN_TEXT`](#redaction-types). -- `continueOnError` defaults to `true`. - -### An [example](https://github.com/skyflowapi/skyflow-java/blob/main/samples/src/main/java/com/example/vault/DetokenizeExample.java) of a detokenize call: +### An [example](https://github.com/skyflowapi/skyflow-java/blob/v3/samples/src/main/java/com/example/vault/BulkDetokenizeSync.java) of a sync bulkDetokenize call: ```java -import com.skyflow.enums.RedactionType; import com.skyflow.errors.SkyflowException; -import com.skyflow.vault.tokens.DetokenizeRequest; -import com.skyflow.vault.tokens.DetokenizeResponse; +import com.skyflow.vault.data.DetokenizeRequest; +import com.skyflow.vault.data.DetokenizeResponse; +import com.skyflow.vault.data.TokenGroupRedactions; import java.util.ArrayList; +import java.util.List; /** - * This example demonstrates how to detokenize sensitive data from tokens stored in a Skyflow vault. - * - * 1. Initializes the Skyflow client. - * 2. Creates a list of tokens (e.g., credit card tokens) that represent the sensitive data. - * 3. Builds a detokenization request using the provided tokens and specifies how the redacted data should be returned. - * 4. Calls the Skyflow vault to detokenize the tokens and retrieves the detokenized data. - * 5. Prints the detokenization response, which contains the detokenized values or errors. + * This sample demonstrates how to perform a synchronous bulk detokenize operation using the Skyflow Java SDK. + * The process involves: + * 1. Setting up credentials and vault configuration + * 2. Creating a list of tokens to detokenize + * 3. Configuring token group redactions + * 4. Building and executing a bulk detokenize request + * 5. Handling the detokenize response or any potential errors */ -public class DetokenizeExample { +public class BulkDetokenizeSync { public static void main(String[] args) { try { - // Initialize Skyflow client + // Initialize Skyflow client // Step 1: Initialize a list of tokens to be detokenized (replace with actual token values) ArrayList tokens = new ArrayList<>(); - tokens.add("9738-1683-0486-1480"); // Replace with your actual token value - tokens.add("6184-6357-8409-6668"); // Replace with your actual token value - tokens.add("4914-9088-2814-3840"); // Replace with your actual token value + tokens.add("b8eea77a-47e1-4d67-a560-fd395cabc82f"); // Replace with your actual token value + tokens.add("6ffb412b-a79d"); // Replace with your actual token value - // Step 2: Create the DetokenizeRequest object with the tokens and redaction type + TokenGroupRedactions tokenGroupRedaction = TokenGroupRedactions.builder() + .tokenGroupName("deterministic_regex") + .redaction("MASKED") + .build(); + List tokenGroupRedactions = new ArrayList<>(); + tokenGroupRedactions.add(tokenGroupRedaction); + + // Step 2: Create the DetokenizeRequest object with the tokens and token group redactions DetokenizeRequest detokenizeRequest = DetokenizeRequest.builder() - .tokens(tokens) // Provide the list of tokens to be detokenized - .continueOnError(false) // Stop the process if any token cannot be detokenized - .redactionType(RedactionType.PLAIN_TEXT) // Specify how the detokenized data should be returned (plain text) - .build(); // Build the detokenization request + .tokens(tokens) // Provide the list of tokens to be detokenized + .tokenGroupredactions(tokenGroupRedactions) // Provide a list of token grpup redactions + .build(); // Build the detokenization request - // Step 3: Call the Skyflow vault to detokenize the provided tokens - DetokenizeResponse detokenizeResponse = skyflowClient.vault("9f27764a10f7946fe56b3258e117").detokenize(detokenizeRequest); - // Replace "9f27764a10f7946fe56b3258e117" with your actual Skyflow vault ID + // Step 3: Call the Skyflow vault to bulk detokenize the provided tokens synchronously + DetokenizeResponse detokenizeResponse = skyflowClient.vault().bulkDetokenizeAsync(detokenizeRequest); // Step 4: Print the detokenization response, which contains the detokenized data System.out.println(detokenizeResponse); @@ -889,65 +558,80 @@ Sample response: ```json { - "detokenizedFields": [{ - "token": "9738-1683-0486-1480", - "value": "4111111111111115", - "type": "STRING", - }, { - "token": "6184-6357-8409-6668", - "value": "4111111111111119", - "type": "STRING", - }, { - "token": "4914-9088-2814-3840", - "value": "4111111111111118", - "type": "STRING", - }] - "errors": [] + "summary": { + "total_tokens": 2, + "total_detokenized": 2, + "total_failed": 0, + }, + "success": [ + { + "index": 0, + "token": "b8eea77a-47e1-4d67-a560-fd395cabc82f", + "value": "xxxx@skyflow.com", + "tokenGroupName": "nondeterministic_regex", + "metadata": { + "skyflowID": "5ddc71a6-3bdb-47e4-9723-259452946349", + "tableName": "table1" + } + }, + ], + "errors": [ + { + "index": 1, + "code": 404, + "error": "Detokenize failed. Token 6ffb412b-a79d is invalid. Specify a valid token.", + } + ] } - ``` -### An example of a detokenize call with `continueOnError` option: +### An [example]() of an async bulkDetokenize call + ```java -import com.skyflow.enums.RedactionType; import com.skyflow.errors.SkyflowException; -import com.skyflow.vault.tokens.DetokenizeRequest; -import com.skyflow.vault.tokens.DetokenizeResponse; +import com.skyflow.vault.data.DetokenizeRequest; +import com.skyflow.vault.data.DetokenizeResponse; +import com.skyflow.vault.data.TokenGroupRedactions; import java.util.ArrayList; +import java.util.List; /** - * This example demonstrates how to detokenize sensitive data (e.g., credit card numbers) from tokens in a Skyflow vault. - * - * 1. Initializes the Skyflow client. - * 2. Creates a list of tokens (e.g., credit card tokens) to be detokenized. - * 3. Builds a detokenization request with the tokens and specifies the redaction type for the detokenized data. - * 4. Calls the Skyflow vault to detokenize the tokens and retrieves the detokenized data. - * 5. Prints the detokenization response, which includes the detokenized values or errors. + * This sample demonstrates how to perform an asynchronous bulk detokenize operation using the Skyflow Java SDK. + * The process involves: + * 1. Setting up credentials and vault configuration + * 2. Creating a list of tokens to detokenize + * 3. Configuring token group redactions + * 4. Building and executing a bulk detokenize request + * 5. Handling the detokenize response or errors using CompletableFuture */ -public class DetokenizeExample { +public class BulkDetokenizeAsync { public static void main(String[] args) { try { - // Initialize Skyflow client + // Initialize Skyflow client // Step 1: Initialize a list of tokens to be detokenized (replace with actual token values) ArrayList tokens = new ArrayList<>(); - tokens.add("9738-1683-0486-1480"); // Example token value 1 - tokens.add("6184-6357-8409-6668"); // Example token value 2 - tokens.add("4914-9088-2814-384"); // Example token value 3 + tokens.add("b8eea77a-47e1-4d67-a560-fd395cabc82f"); // Replace with your actual token value + tokens.add("6ffb412b-a79d"); // Replace with your actual token value + + TokenGroupRedactions tokenGroupRedaction = TokenGroupRedactions.builder() + .tokenGroupName("deterministic_string") + .redaction("MASKED") + .build(); + List tokenGroupRedactions = new ArrayList<>(); + tokenGroupRedactions.add(tokenGroupRedaction); // Step 2: Create the DetokenizeRequest object with the tokens and redaction type DetokenizeRequest detokenizeRequest = DetokenizeRequest.builder() - .tokens(tokens) // Provide the list of tokens to detokenize - .continueOnError(true) // Continue even if some tokens cannot be detokenized - .redactionType(RedactionType.PLAIN_TEXT) // Specify the format for the detokenized data (plain text) - .build(); // Build the detokenization request + .tokens(tokens) // Provide the list of tokens to be detokenized + .tokenGroupredactions(tokenGroupRedactions) // Provide a list of token grpup redactions + .build(); // Build the detokenization request - // Step 3: Call the Skyflow vault to detokenize the provided tokens - DetokenizeResponse detokenizeResponse = skyflowClient.vault("9f27764a10f7946fe56b3258e117").detokenize(detokenizeRequest); - // Replace "9f27764a10f7946fe56b3258e117" with your actual Skyflow vault ID + // Step 3: Call the Skyflow vault to bulk detokenize the provided tokens asynchronously + DetokenizeResponse detokenizeResponse = skyflowClient.vault().bulkDetokenizeAsync(detokenizeRequest); - // Step 4: Print the detokenization response, which contains the detokenized data or errors + // Step 4: Print the detokenization response, which contains the detokenized data System.out.println(detokenizeResponse); } catch (SkyflowException e) { // Step 5: Handle any errors that occur during the detokenization process @@ -962,1632 +646,30 @@ Sample response: ```json { - "detokenizedFields": [{ - "token": "9738-1683-0486-1480", - "value": "4111111111111115", - "type": "STRING", - }, { - "token": "6184-6357-8409-6668", - "value": "4111111111111119", - "type": "STRING", - }] - "errors": [{ - "token": "4914-9088-2814-384", - "error": "Token Not Found", - }] -} -``` - -## Tokenize - -Tokenization replaces sensitive data with unique identifier tokens. This approach protects sensitive information by securely storing the original data while allowing the use of tokens within your application. - -To tokenize data, use the `tokenize` method. The `TokenizeRequest` class creates a tokenize request. In this request, you specify the `values` parameter, which is a list of `ColumnValue` objects. Each `ColumnValue` contains two properties: `value` and `columnGroup`. - -### Construct a tokenize request - -```java -import com.skyflow.errors.SkyflowException; -import com.skyflow.vault.tokens.ColumnValue; -import com.skyflow.vault.tokens.TokenizeRequest; -import com.skyflow.vault.tokens.TokenizeResponse; - -import java.util.ArrayList; - -/** - * This example demonstrates how to tokenize sensitive data (e.g., credit card information) using the Skyflow client, along with corresponding TokenizeRequest schema. - * - */ -public class TokenizeSchema { - public static void main(String[] args) { - try { - // Initialize Skyflow client - // Step 1: Initialize a list of column values to be tokenized (replace with actual sensitive data) - ArrayList columnValues = new ArrayList<>(); - - // Step 2: Create column values for each sensitive data field (e.g., card number and cardholder name) - ColumnValue columnValue1 = ColumnValue.builder().value("").columnGroup("").build(); // Replace and with actual data - ColumnValue columnValue2 = ColumnValue.builder().value("").columnGroup("").build(); // Replace and with actual data - - // Add the created column values to the list - columnValues.add(columnValue1); - columnValues.add(columnValue2); - - // Step 3: Build the TokenizeRequest with the column values - TokenizeRequest tokenizeRequest = TokenizeRequest.builder().values(columnValues).build(); - - // Step 4: Call the Skyflow vault to tokenize the sensitive data - TokenizeResponse tokenizeResponse = skyflowClient.vault("").tokenize(tokenizeRequest); - // Replace with your actual Skyflow vault ID - - // Step 5: Print the tokenization response, which contains the generated tokens or errors - System.out.println(tokenizeResponse); - } catch (SkyflowException e) { - // Step 6: Handle any errors that occur during the tokenization process - System.out.println("Error occurred: "); - e.printStackTrace(); // Print the exception for debugging purposes - } - } -} -``` - -### An [example](https://github.com/skyflowapi/skyflow-java/blob/main/samples/src/main/java/com/example/vault/TokenizeExample.java) of Tokenize call: - -```java -import com.skyflow.errors.SkyflowException; -import com.skyflow.vault.tokens.ColumnValue; -import com.skyflow.vault.tokens.TokenizeRequest; -import com.skyflow.vault.tokens.TokenizeResponse; - -import java.util.ArrayList; - -/** - * This example demonstrates how to tokenize sensitive data (e.g., credit card information) using the Skyflow client. - * - * 1. Initializes the Skyflow client. - * 2. Creates a column value for sensitive data (e.g., credit card number). - * 3. Builds a tokenize request with the column value to be tokenized. - * 4. Sends the request to the Skyflow vault for tokenization. - * 5. Prints the tokenization response, which includes the token or errors. - */ -public class TokenizeExample { - public static void main(String[] args) { - try { - // Initialize Skyflow client - // Step 1: Initialize a list of column values to be tokenized (replace with actual sensitive data) - ArrayList columnValues = new ArrayList<>(); - - // Step 2: Create a column value for the sensitive data (e.g., card number with its column group) - ColumnValue columnValue = ColumnValue.builder() - .value("4111111111111111") // Replace with the actual sensitive data (e.g., card number) - .columnGroup("card_number_cg") // Replace with the actual column group name - .build(); - - // Add the created column value to the list - columnValues.add(columnValue); - - // Step 3: Build the TokenizeRequest with the column value - TokenizeRequest tokenizeRequest = TokenizeRequest.builder().values(columnValues).build(); - - // Step 4: Call the Skyflow vault to tokenize the sensitive data - TokenizeResponse tokenizeResponse = skyflowClient.vault("9f27764a10f7946fe56b3258e117").tokenize(tokenizeRequest); - // Replace "9f27764a10f7946fe56b3258e117" with your actual Skyflow vault ID - - // Step 5: Print the tokenization response, which contains the generated token or any errors - System.out.println(tokenizeResponse); - } catch (SkyflowException e) { - // Step 6: Handle any errors that occur during the tokenization process - System.out.println("Error occurred: "); - e.printStackTrace(); // Print the exception for debugging purposes - } - } -} -``` - -Sample response: - -```json -{ - "tokens": [5479-4229-4622-1393] -} -``` - -## Get - -To retrieve data using Skyflow IDs or unique column values, use the `get` method. The `GetRequest` class creates a get request, where you specify parameters such as the table name, redaction type, Skyflow IDs, column names, column values, and whether to return tokens. If you specify Skyflow IDs, you can't use column names and column values, and the inverse is true—if you specify column names and column values, you can't use Skyflow IDs. - -### Construct a get request - -```java -import com.skyflow.enums.RedactionType; -import com.skyflow.errors.SkyflowException; -import com.skyflow.vault.data.GetRequest; -import com.skyflow.vault.data.GetResponse; - -import java.util.ArrayList; - -/** - * This example demonstrates how to retrieve data from the Skyflow vault using different methods, along with corresponding GetRequest schema. - * - */ -public class GetSchema { - public static void main(String[] args) { - try { - // Initialize Skyflow client - // Step 1: Initialize a list of Skyflow IDs to retrieve records (replace with actual Skyflow IDs) - ArrayList ids = new ArrayList<>(); - ids.add(""); // Replace with actual Skyflow ID - ids.add(""); // Replace with actual Skyflow ID - - // Step 2: Create a GetRequest to retrieve records by Skyflow ID without returning tokens - GetRequest getByIdRequest = GetRequest.builder() - .ids(ids) - .table("") // Replace with the actual table name - .returnTokens(false) // Set to false to avoid returning tokens - .redactionType(RedactionType.PLAIN_TEXT) // Redact data as plain text - .build(); - - // Send the request to the Skyflow vault and retrieve the records - GetResponse getByIdResponse = skyflowClient.vault("").get(getByIdRequest); // Replace with actual Vault ID - System.out.println(getByIdResponse); - - // Step 3: Create another GetRequest to retrieve records by Skyflow ID with tokenized values - GetRequest getTokensRequest = GetRequest.builder() - .ids(ids) - .table("") // Replace with the actual table name - .returnTokens(true) // Set to true to return tokenized values - .build(); - - // Send the request to the Skyflow vault and retrieve the tokenized records - GetResponse getTokensResponse = skyflowClient.vault("").get(getTokensRequest); // Replace with actual Vault ID - System.out.println(getTokensResponse); - - // Step 4: Create a GetRequest to retrieve records based on specific column values - ArrayList columnValues = new ArrayList<>(); - columnValues.add(""); // Replace with the actual column value - columnValues.add(""); // Replace with the actual column value - - GetRequest getByColumnRequest = GetRequest.builder() - .table("") // Replace with the actual table name - .columnName("") // Replace with the column name - .columnValues(columnValues) // Add the list of column values to filter by - .redactionType(RedactionType.PLAIN_TEXT) // Redact data as plain text - .build(); - - // Send the request to the Skyflow vault and retrieve the records filtered by column values - GetResponse getByColumnResponse = skyflowClient.vault("").get(getByColumnRequest); // Replace with actual Vault ID - System.out.println(getByColumnResponse); - } catch (SkyflowException e) { - // Step 5: Handle any errors that occur during the retrieval process - System.out.println("Error occurred: "); - e.printStackTrace(); // Print the exception for debugging purposes - } - } -} -``` - -### Get by skyflow IDs - -Retrieve specific records using `skyflow_ids`. Ideal for fetching exact records when IDs are known. - -An [example](https://github.com/skyflowapi/skyflow-java/blob/main/samples/src/main/java/com/example/vault/GetExample.java) of a get call to retrieve data using Redaction type: - -```java -import com.skyflow.enums.RedactionType; -import com.skyflow.errors.SkyflowException; -import com.skyflow.vault.data.GetRequest; -import com.skyflow.vault.data.GetResponse; - -import java.util.ArrayList; - -/** - * This example demonstrates how to retrieve data from the Skyflow vault using a list of Skyflow IDs. - * - * 1. Initializes the Skyflow client with a given vault ID. - * 2. Creates a request to retrieve records based on Skyflow IDs. - * 3. Specifies that the response should not return tokens. - * 4. Uses plain text redaction type for the retrieved records. - * 5. Prints the response to display the retrieved records. - */ -public class GetExample { - public static void main(String[] args) { - try { - // Initialize Skyflow client - // Step 1: Initialize a list of Skyflow IDs (replace with actual Skyflow IDs) - ArrayList ids = new ArrayList<>(); - ids.add("a581d205-1969-4350-acbe-a2a13eb871a6"); // Replace with actual Skyflow ID - ids.add("5ff887c3-b334-4294-9acc-70e78ae5164a"); // Replace with actual Skyflow ID - - // Step 2: Create a GetRequest to retrieve records based on Skyflow IDs - // The request specifies: - // - `ids`: The list of Skyflow IDs to retrieve - // - `table`: The table from which the records will be retrieved - // - `returnTokens`: Set to false, meaning tokens will not be returned in the response - // - `redactionType`: Set to PLAIN_TEXT, meaning the retrieved records will have data redacted as plain text - GetRequest getByIdRequest = GetRequest.builder() - .ids(ids) - .table("table1") // Replace with the actual table name - .returnTokens(false) // Set to false to avoid returning tokens - .redactionType(RedactionType.PLAIN_TEXT) // Redact data as plain text - .build(); - - // Step 3: Send the request to the Skyflow vault and retrieve the records - GetResponse getByIdResponse = skyflowClient.vault("9f27764a10f7946fe56b3258e117").get(getByIdRequest); // Replace with actual Vault ID - System.out.println(getByIdResponse); // Print the response to the console - - } catch (SkyflowException e) { - // Step 4: Handle any errors that occur during the data retrieval process - System.out.println("Error occurred: "); - e.printStackTrace(); // Print the exception for debugging purposes - } - } -} -``` - -Sample response: - -```json -{ - "data": [ - { - "card_number": "4555555555555553", - "email": "john.doe@gmail.com", - "name": "john doe", - "skyflow_id": "a581d205-1969-4350-acbe-a2a13eb871a6" - }, - { - "card_number": "4555555555555559", - "email": "jane.doe@gmail.com", - "name": "jane doe", - "skyflow_id": "5ff887c3-b334-4294-9acc-70e78ae5164a" - } - ], - "errors": [] -} -``` - -### Get tokens - -Return tokens for records. Ideal for securely processing sensitive data while maintaining data privacy. - -An [example](https://github.com/skyflowapi/skyflow-java/blob/main/samples/src/main/java/com/example/vault/getExample.java) of get call to retrieve tokens using Skyflow IDs: - -```java -import com.skyflow.enums.RedactionType; -import com.skyflow.errors.SkyflowException; -import com.skyflow.vault.data.GetRequest; -import com.skyflow.vault.data.GetResponse; - -import java.util.ArrayList; - -/** - * This example demonstrates how to retrieve data from the Skyflow vault and return tokens along with the records. - * - * 1. Initializes the Skyflow client with a given vault ID. - * 2. Creates a request to retrieve records based on Skyflow IDs and ensures tokens are returned. - * 3. Prints the response to display the retrieved records along with the tokens. - */ -public class GetExample { - public static void main(String[] args) { - try { - // Initialize Skyflow client - // Step 1: Initialize a list of Skyflow IDs (replace with actual Skyflow IDs) - ArrayList ids = new ArrayList<>(); - ids.add("a581d205-1969-4350-acbe-a2a13eb871a6"); // Replace with actual Skyflow ID - ids.add("5ff887c3-b334-4294-9acc-70e78ae5164a"); // Replace with actual Skyflow ID - - // Step 2: Create a GetRequest to retrieve records based on Skyflow IDs - // The request specifies: - // - `ids`: The list of Skyflow IDs to retrieve - // - `table`: The table from which the records will be retrieved - // - `returnTokens`: Set to true, meaning tokens will be included in the response - GetRequest getTokensRequest = GetRequest.builder() - .ids(ids) - .table("table1") // Replace with the actual table name - .returnTokens(true) // Set to true to include tokens in the response - .build(); - - // Step 3: Send the request to the Skyflow vault and retrieve the records with tokens - GetResponse getTokensResponse = skyflowClient.vault("9f27764a10f7946fe56b3258e117").get(getTokensRequest); // Replace with actual Vault ID - System.out.println(getTokensResponse); // Print the response to the console - - } catch (SkyflowException e) { - // Step 4: Handle any errors that occur during the data retrieval process - System.out.println("Error occurred: "); - e.printStackTrace(); // Print the exception for debugging purposes - } - } -} -``` - -Sample response: - -```json -{ - "data": [ - { - "card_number": "3998-2139-0328-0697", - "email": "c9a6c9555060@82c092e7.bd52", - "name": "82c092e7-74c0-4e60-bd52-c9a6c9555060", - "skyflow_id": "a581d205-1969-4350-acbe-a2a13eb871a6" - }, - { - "card_number": "3562-0140-8820-7499", - "email": "6174366e2bc6@59f82e89.93fc", - "name": "59f82e89-138e-4f9b-93fc-6174366e2bc6", - "skyflow_id": "5ff887c3-b334-4294-9acc-70e78ae5164a" - } - ], - "errors": [] -} -``` - -### Get By column name and column values - -Retrieve records by unique column values. Ideal for querying data without knowing Skyflow IDs, using alternate unique identifiers. - -An [example](https://github.com/skyflowapi/skyflow-java/blob/main/samples/src/main/java/com/example/vault/GetExample.java) of get call to retrieve data using column name and column values: - -```java -import com.skyflow.enums.RedactionType; -import com.skyflow.errors.SkyflowException; -import com.skyflow.vault.data.GetRequest; -import com.skyflow.vault.data.GetResponse; - -import java.util.ArrayList; - -/** - * This example demonstrates how to retrieve data from the Skyflow vault based on column values. - * - * 1. Initializes the Skyflow client with a given vault ID. - * 2. Creates a request to retrieve records based on specific column values (e.g., email addresses). - * 3. Prints the response to display the retrieved records after redacting sensitive data based on the specified redaction type. - */ -public class GetExample { - public static void main(String[] args) { - try { - // Initialize Skyflow client - // Step 1: Initialize a list of column values (email addresses in this case) - ArrayList columnValues = new ArrayList<>(); - columnValues.add("john.doe@gmail.com"); // Example email address - columnValues.add("jane.doe@gmail.com"); // Example email address - - // Step 2: Create a GetRequest to retrieve records based on column values - // The request specifies: - // - `table`: The table from which the records will be retrieved - // - `columnName`: The column to filter the records by (e.g., "email") - // - `columnValues`: The list of values to match in the specified column - // - `redactionType`: Defines how sensitive data should be redacted (set to PLAIN_TEXT here) - GetRequest getByColumnRequest = GetRequest.builder() - .table("table1") // Replace with the actual table name - .columnName("email") // The column name to filter by (e.g., "email") - .columnValues(columnValues) // The list of column values to match - .redactionType(RedactionType.PLAIN_TEXT) // Set the redaction type (e.g., PLAIN_TEXT) - .build(); - - // Step 3: Send the request to the Skyflow vault and retrieve the records - GetResponse getByColumnResponse = skyflowClient.vault("9f27764a10f7946fe56b3258e117").get(getByColumnRequest); // Replace with actual Vault ID - System.out.println(getByColumnResponse); // Print the response to the console - - } catch (SkyflowException e) { - // Step 4: Handle any errors that occur during the data retrieval process - System.out.println("Error occurred: "); - e.printStackTrace(); // Print the exception for debugging purposes - } - } -} -``` - -Sample response: - -```json -{ - "data": [ - { - "card_number": "4555555555555553", - "email": "john.doe@gmail.com", - "name": "john doe", - "skyflow_id": "a581d205-1969-4350-acbe-a2a13eb871a6" - }, - { - "card_number": "4555555555555559", - "email": "jane.doe@gmail.com", - "name": "jane doe", - "skyflow_id": "5ff887c3-b334-4294-9acc-70e78ae5164a" - } - ], - "errors": [] -} -``` - -### Redaction types - -Redaction types determine how sensitive data is displayed when retrieved from the vault. - -#### **Available Redaction Types** - -- `DEFAULT`: Applies the vault-configured default redaction setting. -- `REDACTED`: Completely removes sensitive data from view. -- `MASKED`: Partially obscures sensitive information. -- `PLAIN_TEXT`: Displays the full, unmasked data. - -#### **Choosing the Right Redaction Type** - -- Use `REDACTED` for scenarios requiring maximum data protection to prevent exposure of sensitive information. -- Use `MASKED` to provide partial visibility of sensitive data for less critical use cases. -- Use `PLAIN_TEXT` for internal, authorized access where full data visibility is necessary. - -## Update - -To update data in your vault, use the `update` method. The `UpdateRequest` class is used to create an update request, -where you specify parameters such as the table name, data (as a map of key value pairs), tokens, returnTokens, and -tokenStrict. If `returnTokens` is set to `true`, Skyflow returns tokens for the updated records. If `returnTokens` is -set to `false`, Skyflow returns IDs for the updated records. - -### Construct an update request - -```java -import com.skyflow.enums.TokenMode; -import com.skyflow.errors.SkyflowException; -import com.skyflow.vault.data.UpdateRequest; -import com.skyflow.vault.data.UpdateResponse; - -import java.util.HashMap; - -/** - * This example demonstrates how to update records in the Skyflow vault by providing new data and/or tokenized values, along with corresponding UpdateRequest schema. - * - */ -public class UpdateSchema { - public static void main(String[] args) { - try { - // Initialize Skyflow client - // Step 1: Prepare the data to update in the vault - // Use a HashMap to store the data that will be updated in the specified table - HashMap data = new HashMap<>(); - data.put("skyflow_id", ""); // Skyflow ID for identifying the record to update - data.put("", ""); // Example of a column name and its value to update - data.put("", ""); // Another example of a column name and its value to update - - // Step 2: Prepare the tokens (if necessary) for certain columns that require tokenization - // Use a HashMap to specify columns that need tokens in the update request - HashMap tokens = new HashMap<>(); - tokens.put("", ""); // Example of a column name that should be tokenized - - // Step 3: Create an UpdateRequest to specify the update operation - // The request includes the table name, token mode, data, tokens, and the returnTokens flag - UpdateRequest updateRequest = UpdateRequest.builder() - .table("") // Replace with the actual table name to update - .tokenMode(TokenMode.ENABLE) // Specifies the tokenization mode (ENABLE means tokenization is applied) - .data(data) // The data to update in the record - .tokens(tokens) // The tokens associated with specific columns - .returnTokens(true) // Specify whether to return tokens in the response - .build(); - - // Step 4: Send the request to the Skyflow vault and update the record - UpdateResponse updateResponse = skyflowClient.vault("").update(updateRequest); // Replace with actual Vault ID - System.out.println(updateResponse); // Print the response to confirm the update result - - } catch (SkyflowException e) { - // Step 5: Handle any errors that occur during the update operation - System.out.println("Error occurred: "); - e.printStackTrace(); // Print the exception for debugging purposes - } - } -} -``` - -### An [example](https://github.com/skyflowapi/skyflow-java/blob/main/samples/src/main/java/com/example/vault/UpdateExample.java) of update call - -```java -import com.skyflow.enums.TokenMode; -import com.skyflow.errors.SkyflowException; -import com.skyflow.vault.data.UpdateRequest; -import com.skyflow.vault.data.UpdateResponse; - -import java.util.HashMap; - -/** - * This example demonstrates how to update a record in the Skyflow vault with specified data and tokens. - * - * 1. Initializes the Skyflow client with a given vault ID. - * 2. Constructs an update request with data to modify and tokens to include. - * 3. Sends the request to update the record in the vault. - * 4. Prints the response to confirm the success or failure of the update operation. - */ -public class UpdateExample { - public static void main(String[] args) { - try { - // Initialize Skyflow client - // Step 1: Prepare the data to update in the vault - // A HashMap is used to store the data that will be updated in the specified table - HashMap data = new HashMap<>(); - data.put("skyflow_id", "5b699e2c-4301-4f9f-bcff-0a8fd3057413"); // Skyflow ID identifies the record to update - data.put("name", "john doe"); // Updating the "name" column with a new value - data.put("card_number", "4111111111111115"); // Updating the "card_number" column with a new value - - // Step 2: Prepare the tokens to include in the update request - // Tokens can be included to update sensitive data with tokenized values - HashMap tokens = new HashMap<>(); - tokens.put("name", "72b8ffe3-c8d3-4b4f-8052-38b2a7405b5a"); // Tokenized value for the "name" column - - // Step 3: Create an UpdateRequest to define the update operation - // The request specifies the table name, token mode, data, and tokens for the update - UpdateRequest updateRequest = UpdateRequest.builder() - .table("table1") // Replace with the actual table name to update - .tokenMode(TokenMode.ENABLE) // Token mode enabled to allow tokenization of sensitive data - .data(data) // The data to update in the record - .tokens(tokens) // The tokenized values for sensitive columns - .build(); - - // Step 4: Send the update request to the Skyflow vault - UpdateResponse updateResponse = skyflowClient.vault("9f27764a10f7946fe56b3258e117").update(updateRequest); // Replace with your actual Vault ID - System.out.println(updateResponse); // Print the response to confirm the update result - - } catch (SkyflowException e) { - // Step 5: Handle any exceptions that occur during the update operation - System.out.println("Error occurred: "); - e.printStackTrace(); // Print the exception stack trace for debugging purposes - } - } -} -``` - -Sample response: - -- When `returnTokens` is set to `true` - -```json -{ - "skyflowId": "5b699e2c-4301-4f9f-bcff-0a8fd3057413", - "name": "72b8ffe3-c8d3-4b4f-8052-38b2a7405b5a", - "card_number": "4315-7650-1359-9681" -} -``` - -- When `returnTokens` is set to `false` - -```json -{ - "skyflowId": "5b699e2c-4301-4f9f-bcff-0a8fd3057413" -} -``` - -## Delete - -To delete records using Skyflow IDs, use the `delete` method. The `DeleteRequest` class accepts a list of Skyflow IDs -that you want to delete, as shown below: - -### Construct a delete request - -```java -import com.skyflow.errors.SkyflowException; -import com.skyflow.vault.data.DeleteRequest; -import com.skyflow.vault.data.DeleteResponse; - -import java.util.ArrayList; - -/** - * This example demonstrates how to delete records from a Skyflow vault using specified Skyflow IDs, along with corresponding DeleteRequest schema. - * - */ -public class DeleteSchema { - public static void main(String[] args) { - try { - // Initialize Skyflow client - // Step 1: Prepare a list of Skyflow IDs for the records to delete - // The list stores the Skyflow IDs of the records that need to be deleted from the vault - ArrayList ids = new ArrayList<>(); - ids.add(""); // Replace with actual Skyflow ID 1 - ids.add(""); // Replace with actual Skyflow ID 2 - ids.add(""); // Replace with actual Skyflow ID 3 - - // Step 2: Create a DeleteRequest to define the delete operation - // The request specifies the table from which to delete the records and the IDs of the records to delete - DeleteRequest deleteRequest = DeleteRequest.builder() - .ids(ids) // List of Skyflow IDs to delete - .table("") // Replace with the actual table name from which to delete - .build(); - - // Step 3: Send the delete request to the Skyflow vault - DeleteResponse deleteResponse = skyflowClient.vault("").delete(deleteRequest); // Replace with your actual Vault ID - System.out.println(deleteResponse); // Print the response to confirm the delete result - - } catch (SkyflowException e) { - // Step 4: Handle any exceptions that occur during the delete operation - System.out.println("Error occurred: "); - e.printStackTrace(); // Print the exception stack trace for debugging purposes - } - } -} -``` - -### An [example](https://github.com/skyflowapi/skyflow-java/blob/main/samples/src/main/java/com/example/vault/DeleteExample.java) of delete call: - -```java -import com.skyflow.errors.SkyflowException; -import com.skyflow.vault.data.DeleteRequest; -import com.skyflow.vault.data.DeleteResponse; - -import java.util.ArrayList; - -/** - * This example demonstrates how to delete records from a Skyflow vault using specified Skyflow IDs. - * - * 1. Initializes the Skyflow client with a given Vault ID. - * 2. Constructs a delete request by specifying the IDs of the records to delete. - * 3. Sends the delete request to the Skyflow vault to delete the specified records. - * 4. Prints the response to confirm the success or failure of the delete operation. - */ -public class DeleteExample { - public static void main(String[] args) { - try { - // Initialize Skyflow client - // Step 1: Prepare a list of Skyflow IDs for the records to delete - // The list stores the Skyflow IDs of the records that need to be deleted from the vault - ArrayList ids = new ArrayList<>(); - ids.add("9cbf66df-6357-48f3-b77b-0f1acbb69280"); // Replace with actual Skyflow ID 1 - ids.add("ea74bef4-f27e-46fe-b6a0-a28e91b4477b"); // Replace with actual Skyflow ID 2 - ids.add("47700796-6d3b-4b54-9153-3973e281cafb"); // Replace with actual Skyflow ID 3 - - // Step 2: Create a DeleteRequest to define the delete operation - // The request specifies the table from which to delete the records and the IDs of the records to delete - DeleteRequest deleteRequest = DeleteRequest.builder() - .ids(ids) // List of Skyflow IDs to delete - .table("table1") // Replace with the actual table name from which to delete - .build(); - - // Step 3: Send the delete request to the Skyflow vault - DeleteResponse deleteResponse = skyflowClient.vault("9f27764a10f7946fe56b3258e117").delete(deleteRequest); // Replace with your actual Vault ID - System.out.println(deleteResponse); // Print the response to confirm the delete result - - } catch (SkyflowException e) { - // Step 4: Handle any exceptions that occur during the delete operation - System.out.println("Error occurred: "); - e.printStackTrace(); // Print the exception stack trace for debugging purposes - } - } -} -``` - -Sample response: - -```json -{ - "deletedIds": [ - "9cbf66df-6357-48f3-b77b-0f1acbb69280", - "ea74bef4-f27e-46fe-b6a0-a28e91b4477b", - "47700796-6d3b-4b54-9153-3973e281cafb" - ] -} -``` - -## Query - -To retrieve data with SQL queries, use the `query` method. The `QueryRequest` class accepts a `query` parameter, as shown below. - -### Construct a query request - -Refer to [Query your data](https://docs.skyflow.com/query-data/) and [Execute Query](https://docs.skyflow.com/record/#QueryService_ExecuteQuery) for guidelines and restrictions on supported SQL statements, operators, and keywords. - -```java -import com.skyflow.errors.SkyflowException; -import com.skyflow.vault.data.QueryRequest; -import com.skyflow.vault.data.QueryResponse; - -/** - * This example demonstrates how to execute a custom SQL query on a Skyflow vault, along with QueryRequest schema. - * - */ -public class QuerySchema { - public static void main(String[] args) { - try { - // Initialize Skyflow client - // Step 1: Define the SQL query to execute on the Skyflow vault - // Replace "" with the actual SQL query you want to run - String query = ""; // Example: "SELECT * FROM table1 WHERE column1 = 'value'" - - // Step 2: Create a QueryRequest with the specified SQL query - QueryRequest queryRequest = QueryRequest.builder() - .query(query) // SQL query to execute - .build(); - - // Step 3: Execute the query request on the specified Skyflow vault - QueryResponse queryResponse = skyflowClient.vault("").query(queryRequest); // Replace with your actual Vault ID - System.out.println(queryResponse); // Print the response containing the query results - - } catch (SkyflowException e) { - // Step 4: Handle any exceptions that occur during the query execution - System.out.println("Error occurred: "); - e.printStackTrace(); // Print the exception stack trace for debugging - } - } -} -``` - -### An [example](https://github.com/skyflowapi/skyflow-java/blob/main/samples/src/main/java/com/example/vault/QueryExample.java) of query call - -```java -import com.skyflow.errors.SkyflowException; -import com.skyflow.vault.data.QueryRequest; -import com.skyflow.vault.data.QueryResponse; - -/** - * This example demonstrates how to execute a SQL query on a Skyflow vault to retrieve data. - * - * 1. Initializes the Skyflow client with the Vault ID. - * 2. Constructs a query request with a specified SQL query. - * 3. Executes the query against the Skyflow vault. - * 4. Prints the response from the query execution. - */ -public class QueryExample { - public static void main(String[] args) { - try { - // Initialize Skyflow client - // Step 1: Define the SQL query - // Example query: Retrieve all records from the "cards" table with a specific skyflow_id - String query = "SELECT * FROM cards WHERE skyflow_id='3ea3861-x107-40w8-la98-106sp08ea83f'"; - - // Step 2: Create a QueryRequest with the SQL query - QueryRequest queryRequest = QueryRequest.builder() - .query(query) // SQL query to execute - .build(); - - // Step 3: Execute the query request on the specified Skyflow vault - QueryResponse queryResponse = skyflowClient.vault("9f27764a10f7946fe56b3258e117").query(queryRequest); // Vault ID: 9f27764a10f7946fe56b3258e117 - System.out.println(queryResponse); // Print the query response (contains query results) - - } catch (SkyflowException e) { - // Step 4: Handle any exceptions that occur during the query execution - System.out.println("Error occurred: "); - e.printStackTrace(); // Print the exception stack trace for debugging - } - } -} -``` - -Sample response: - -```json -{ - "fields": [ - { - "card_number": "XXXXXXXXXXXX1112", - "name": "S***ar", - "skyflow_id": "3ea3861-x107-40w8-la98-106sp08ea83f", - "tokenizedData": null - } - ] -} -``` - -# Detect -Skyflow Detect enables you to deidentify and reidentify sensitive data in text and files, supporting advanced privacy-preserving workflows. The Detect API supports the following operations: - -## Deidentify Text -To deidentify text, use the `deidentifyText` method. The `DeidentifyTextRequest` class creates a deidentify text request, which includes the text to be deidentified. Additionally, you can provide optional parameters using the `DeidentifyTextOptions` class. - -### Construct an deidentify text request - -```java -import com.skyflow.enums.DetectEntities; -import com.skyflow.vault.detect.DateTransformation; -import com.skyflow.vault.detect.DeidentifyTextRequest; -import com.skyflow.vault.detect.TokenFormat; -import com.skyflow.vault.detect.Transformations; -import com.skyflow.vault.detect.DeidentifyTextResponse; - -import java.util.ArrayList; -import java.util.List; - -/** - * This example demonstrate to build deidentify text request. - */ -public class DeidentifyTextSchema { - - public static void main(String[] args) { - - // Step 1: Initialise the Skyflow client by configuring the credentials & vault config. - - // Step 2: Configure the options for deidentify text - - // Replace with the entity you want to detect - List detectEntitiesList = new ArrayList<>(); - detectEntitiesList.add(DetectEntities.SSN); - - // Replace with the entity you want to detect with vault token - List vaultTokenList = new ArrayList<>(); - vaultTokenList.add(DetectEntities.CREDIT_CARD); - - // Replace with the entity you want to detect with entity only - List entityOnlyList = new ArrayList<>(); - entityOnlyList.add(DetectEntities.SSN); - - // Replace with the entity you want to detect with entity unique counter - List entityUniqueCounterList = new ArrayList<>(); - entityUniqueCounterList.add(DetectEntities.SSN); - - // Replace with the regex patterns you want to allow during deidentification - List allowRegexList = new ArrayList<>(); - allowRegexList.add(""); - - // Replace with the regex patterns you want to restrict during deidentification - List restrictRegexList = new ArrayList<>(); - restrictRegexList.add("YOUR_RESTRICT_REGEX_LIST"); - - // Configure Token Format - TokenFormat tokenFormat = TokenFormat.builder() - .vaultToken(vaultTokenList) - .entityOnly(entityOnlyList) - .entityUniqueCounter(entityUniqueCounterList) - .build(); - - // Configure Transformation - List detectEntitiesTransformationList = new ArrayList<>(); - detectEntitiesTransformationList.add(DetectEntities.DOB); // Replace with the entity you want to transform - - DateTransformation dateTransformation = new DateTransformation(20, 5, detectEntitiesTransformationList); - Transformations transformations = new Transformations(dateTransformation); - - // Step 3: Create a deidentify text request for the vault - DeidentifyTextRequest deidentifyTextRequest = DeidentifyTextRequest.builder() - .text("") // Replace with the text you want to deidentify - .entities(detectEntitiesList) - .allowRegexList(allowRegexList) - .restrictRegexList(restrictRegexList) - .tokenFormat(tokenFormat) - .transformations(transformations) - .build(); - - // Step 4: Use the Skyflow client to perform the deidentifyText operation - // Replace with your actual vault ID - DeidentifyTextResponse deidentifyTextResponse = skyflowClient.detect("").deidentifyText(deidentifyTextRequest); - - // Step 5: Print the response - System.out.println("Deidentify text Response: " + deidentifyTextResponse); - } -} - -``` - -## An [example](https://github.com/skyflowapi/skyflow-java/blob/beta-release/25.6.2/samples/src/main/java/com/example/detect/DeidentifyTextExample.java) of deidentify text: -```java -import java.util.ArrayList; -import java.util.List; - -import com.skyflow.enums.DetectEntities; -import com.skyflow.errors.SkyflowException; -import com.skyflow.vault.detect.DateTransformation; -import com.skyflow.vault.detect.DeidentifyTextRequest; -import com.skyflow.vault.detect.DeidentifyTextResponse; -import com.skyflow.vault.detect.TokenFormat; -import com.skyflow.vault.detect.Transformations; - -/** - * Skyflow Deidentify Text Example - *

- * This example demonstrates how to use the Skyflow SDK to deidentify text data - * across multiple vaults. It includes: - * 1. Setting up credentials and vault configurations. - * 2. Creating a Skyflow client with multiple vaults. - * 3. Performing deidentify of text with various options. - * 4. Handling responses and errors. - */ - -public class DeidentifyTextExample { - public static void main(String[] args) throws SkyflowException { - - // Step 1: Initialise the Skyflow client by configuring the credentials & vault config. - - // Step 2: Configuring the different options for deidentify - - // Replace with the entity you want to detect - List detectEntitiesList = new ArrayList<>(); - detectEntitiesList.add(DetectEntities.SSN); - detectEntitiesList.add(DetectEntities.CREDIT_CARD); - - // Replace with the entity you want to detect with vault token - List vaultTokenList = new ArrayList<>(); - vaultTokenList.add(DetectEntities.SSN); - vaultTokenList.add(DetectEntities.CREDIT_CARD); - - // Configure Token Format - TokenFormat tokenFormat = TokenFormat.builder() - .vaultToken(vaultTokenList) - .build(); - - // Configure Transformation for deidentified entities - List detectEntitiesTransformationList = new ArrayList<>(); - detectEntitiesTransformationList.add(DetectEntities.DOB); // Replace with the entity you want to transform - - DateTransformation dateTransformation = new DateTransformation(20, 5, detectEntitiesTransformationList); - Transformations transformations = new Transformations(dateTransformation); - - // Step 3: invoking Deidentify text on the vault - try { - // Create a deidentify text request for the vault - DeidentifyTextRequest deidentifyTextRequest = DeidentifyTextRequest.builder() - .text("My SSN is 123-45-6789 and my card is 4111 1111 1111 1111.") // Replace with your deidentify text - .entities(detectEntitiesList) - .tokenFormat(tokenFormat) - .transformations(transformations) - .build(); - // Replace `9f27764a10f7946fe56b3258e117` with the acutal vault id - DeidentifyTextResponse deidentifyTextResponse = skyflowClient.detect("9f27764a10f7946fe56b3258e117").deidentifyText(deidentifyTextRequest); - - System.out.println("Deidentify text Response: " + deidentifyTextResponse); - } catch (SkyflowException e) { - System.err.println("Error occurred during deidentify: "); - e.printStackTrace(); // Print the exception for debugging purposes - } - } -} -``` - -Sample Response: -```json -{ - "processedText": "My SSN is [SSN_IWdexZe] and my card is [CREDIT_CARD_rUzMjdQ].", - "entities": [ + "summary": { + "total_tokens": 2, + "total_detokenized": 2, + "total_failed": 0, + }, + "success": [ { - "token": "SSN_IWdexZe", - "value": "123-45-6789", - "textIndex": { - "start": 10, - "end": 21 - }, - "processedIndex": { - "start": 10, - "end": 23 - }, - "entity": "SSN", - "scores": { - "SSN": 0.9384 + "index": 0, + "token": "b8eea77a-47e1-4d67-a560-fd395cabc82f", + "value": "xxxx@skyflow.com", + "tokenGroupName": "nondeterministic_regex", + "metadata": { + "skyflowID": "5ddc71a6-3bdb-47e4-9723-259452946349", + "tableName": "table1" } }, - { - "token": "CREDIT_CARD_rUzMjdQ", - "value": "4111 1111 1111 1111", - "textIndex": { - "start": 37, - "end": 56 - }, - "processedIndex": { - "start": 39, - "end": 60 - }, - "entity": "CREDIT_CARD", - "scores": { - "CREDIT_CARD": 0.9051 - } - } - ], - "wordCount": 9, - "charCount": 57 -} -``` - -## Reidentify Text -To reidentify text, use the `reidentifyText` method. The `ReidentifyTextRequest` class creates a reidentify text request, which includes the redacted or deidentified text to be reidentified. Additionally, you can provide optional parameters using the ReidentifyTextOptions class to control how specific entities are returned (as redacted, masked, or plain text). - -### Construct an reidentify text request - -```java -import com.skyflow.enums.DetectEntities; -import com.skyflow.vault.detect.ReidentifyTextRequest; -import com.skyflow.vault.detect.ReidentifyTextResponse; - -import java.util.ArrayList; -import java.util.List; - -/** - * This example demonstrates how to build a reidentify text request. - */ -public class ReidentifyTextSchema { - public static void main(String[] args) { - // Step 1: Initialise the Skyflow client by configuring the credentials & vault config. - - // Step 2: Configuring the different options for reidentify - List maskedEntity = new ArrayList<>(); - maskedEntity.add(DetectEntities.CREDIT_CARD); // Replace with the entity you want to mask - - List plainTextEntity = new ArrayList<>(); - plainTextEntity.add(DetectEntities.SSN); // Replace with the entity you want to keep in plain text - - // List redactedEntity = new ArrayList<>(); - // redactedEntity.add(DetectEntities.SSN); // Replace with the entity you want to redact - - - // Step 3: Create a reidentify text request with the configured entities - ReidentifyTextRequest reidentifyTextRequest = ReidentifyTextRequest.builder() - .text("My SSN is [SSN_IWdexZe] and my card is [CREDIT_CARD_rUzMjdQ].") // Replace with your deidentify text - .maskedEntities(maskedEntity) -// .redactedEntities(redactedEntity) - .plainTextEntities(plainTextEntity) - .build(); - - // Step 4: Invoke reidentify text on the vault - ReidentifyTextResponse reidentifyTextResponse = skyflowClient.detect("").reidentifyText(reidentifyTextRequest); - System.out.println("Reidentify text Response: " + reidentifyTextResponse); - } -} -``` - -## An [example](https://github.com/skyflowapi/skyflow-java/blob/beta-release/25.6.2/samples/src/main/java/com/example/detect/ReidentifyTextExample.java) of Reidentify text - -```java -import com.skyflow.enums.DetectEntities; -import com.skyflow.errors.SkyflowException; -import com.skyflow.vault.detect.ReidentifyTextRequest; -import com.skyflow.vault.detect.ReidentifyTextResponse; - -import java.util.ArrayList; -import java.util.List; - -/** - * Skyflow Reidentify Text Example - *

- * This example demonstrates how to use the Skyflow SDK to reidentify text data - * across multiple vaults. It includes: - * 1. Setting up credentials and vault configurations. - * 2. Creating a Skyflow client with multiple vaults. - * 3. Performing reidentify of text with various options. - * 4. Handling responses and errors. - */ - -public class ReidentifyTextExample { - public static void main(String[] args) throws SkyflowException { - // Step 1: Initialise the Skyflow client by configuring the credentials & vault config. - - // Step 2: Configuring the different options for reidentify - List maskedEntity = new ArrayList<>(); - maskedEntity.add(DetectEntities.CREDIT_CARD); // Replace with the entity you want to mask - - List plainTextEntity = new ArrayList<>(); - plainTextEntity.add(DetectEntities.SSN); // Replace with the entity you want to keep in plain text - - try { - // Step 3: Create a reidentify text request with the configured options - ReidentifyTextRequest reidentifyTextRequest = ReidentifyTextRequest.builder() - .text("My SSN is [SSN_IWdexZe] and my card is [CREDIT_CARD_rUzMjdQ].") // Replace with your deidentify text - .maskedEntities(maskedEntity) - .plainTextEntities(plainTextEntity) - .build(); - - // Step 4: Invoke Reidentify text on the vault - // Replace `9f27764a10f7946fe56b3258e117` with the acutal vault id - ReidentifyTextResponse reidentifyTextResponse = skyflowClient.detect("9f27764a10f7946fe56b3258e117").reidentifyText(reidentifyTextRequest); - - // Handle the response from the reidentify text request - System.out.println("Reidentify text Response: " + reidentifyTextResponse); - } catch (SkyflowException e) { - System.err.println("Error occurred during reidentify : "); - e.printStackTrace(); - } - } -} -``` - -Sample Response: - -```json -{ - "processedText":"My SSN is 123-45-6789 and my card is XXXXX1111." -} -``` - -## Deidentify file -To deidentify files, use the `deidentifyFile` method. The `DeidentifyFileRequest` class creates a deidentify file request, which includes the file to be deidentified (such as images, PDFs, audio, documents, spreadsheets, or presentations). Additionally, you can provide optional parameters using the DeidentifyFileOptions class to control how entities are detected and deidentified, as well as how the output is generated for different file types. - -### Construct an deidentify file request - -```java -import com.skyflow.config.Credentials; -import com.skyflow.config.VaultConfig; -import com.skyflow.enums.Env; -import com.skyflow.enums.LogLevel; -import com.skyflow.enums.MaskingMethod; -import com.skyflow.errors.SkyflowException; -import com.skyflow.vault.detect.DeidentifyFileRequest; -import com.skyflow.vault.detect.DeidentifyFileResponse; - -import java.io.File; - -/** - * This example demonstrates how to build a deidentify file request. - */ - -public class DeidentifyFileSchema { - - public static void main(String[] args) { - // Step 1: Initialise the Skyflow client by configuring the credentials & vault config. - - // Step 2: Create a deidentify file request with all options - - // Create file object - File file = new File(""); // Replace with the path to the file you want to deidentify - - // Create file input using the file object - FileInput fileInput = FileInput.builder() - .file(file) - // .filePath("") // Alternatively, you can use .filePath() - .build(); - - // Output configuration - String outputDirectory = ""; // Replace with the desired output directory to save the deidentified file - - // Entities to detect - // List detectEntities = new ArrayList<>(); - // detectEntities.add(DetectEntities.IP_ADDRESS); // Replace with the entities you want to detect - - // Image-specific options - // Boolean outputProcessedImage = true; // Include processed image in output - // Boolean outputOcrText = true; // Include OCR text in output - MaskingMethod maskingMethod = MaskingMethod.BLACKBOX; // Masking method for images - - // PDF-specific options - // Integer pixelDensity = 15; // Pixel density for PDF processing - // Integer maxResolution = 2000; // Max resolution for PDF - - // Audio-specific options - // Boolean outputProcessedAudio = true; // Include processed audio - // DetectOutputTranscriptions outputTanscription = DetectOutputTranscriptions.PLAINTEXT_TRANSCRIPTION; // Transcription type - - // Audio bleep configuration - // AudioBleep audioBleep = AudioBleep.builder() - // .frequency(5D) // Pitch in Hz - // .startPadding(7D) // Padding at start (seconds) - // .stopPadding(8D) // Padding at end (seconds) - // .build(); - - Integer waitTime = 20; // Max wait time for response (max 64 seconds) - - DeidentifyFileRequest deidentifyFileRequest = DeidentifyFileRequest.builder() - .file(fileInput) - .waitTime(waitTime) - .entities(detectEntities) - .outputDirectory(outputDirectory) - .maskingMethod(maskingMethod) - // .outputProcessedImage(outputProcessedImage) - // .outputOcrText(outputOcrText) - // .pixelDensity(pixelDensity) - // .maxResolution(maxResolution) - // .outputProcessedAudio(outputProcessedAudio) - // .outputTranscription(outputTanscription) - // .bleep(audioBleep) - .build(); - - - DeidentifyFileResponse deidentifyFileResponse = skyflowClient.detect("").deidentifyFile(deidentifyFileRequest); - System.out.println("Deidentify file response: " + deidentifyFileResponse.toString()); - } -} -``` - -## An [example](https://github.com/skyflowapi/skyflow-java/blob/beta-release/25.6.2/samples/src/main/java/com/example/detect/DeidentifyFileExample.java) of Deidentify file - -```java -import java.io.File; - -import com.skyflow.enums.MaskingMethod; -import com.skyflow.errors.SkyflowException; -import com.skyflow.vault.detect.DeidentifyFileRequest; -import com.skyflow.vault.detect.DeidentifyFileResponse; - -/** - * Skyflow Deidentify File Example - *

- * This example demonstrates how to use the Skyflow SDK to deidentify file - * It has all available options for deidentifying files. - * Supported file types: images (jpg, png, etc.), pdf, audio (mp3, wav), documents, spreadsheets, presentations, structured text. - * It includes: - * 1. Configure credentials - * 2. Set up vault configuration - * 3. Create a deidentify file request with all options - * 4. Call deidentifyFile to deidentify file. - * 5. Handle response and errors - */ -public class DeidentifyFileExample { - - public static void main(String[] args) throws SkyflowException { - // Step 1: Initialise the Skyflow client by configuring the credentials & vault config. - try { - // Step 2: Create a deidentify file request with all options - - - // Create file object - File file = new File("sensitive-folder/personal-info.txt"); // Replace with the path to the file you want to deidentify - - // Create file input using the file object - FileInput fileInput = FileInput.builder() - .file(file) - // .filePath("") // Alternatively, you can use .filePath() - .build(); - - // Output configuration - String outputDirectory = "deidenfied-file/"; // Replace with the desired output directory to save the deidentified file - - // Entities to detect - // List detectEntities = new ArrayList<>(); - // detectEntities.add(DetectEntities.IP_ADDRESS); // Replace with the entities you want to detect - - // Image-specific options - // Boolean outputProcessedImage = true; // Include processed image in output - // Boolean outputOcrText = true; // Include OCR text in output - MaskingMethod maskingMethod = MaskingMethod.BLACKBOX; // Masking method for images - - Integer waitTime = 20; // Max wait time for response (max 64 seconds) - - DeidentifyFileRequest deidentifyFileRequest = DeidentifyFileRequest.builder() - .file(fileInput) - .waitTime(waitTime) - .outputDirectory(outputDirectory) - .maskingMethod(maskingMethod) - .build(); - - // Step 3: Invoking deidentifyFile - // Replace `9f27764a10f7946fe56b3258e117` with the acutal vault id - DeidentifyFileResponse deidentifyFileResponse = skyflowClient.detect("9f27764a10f7946fe56b3258e117").deidentifyFile(deidentifyFileRequest); - System.out.println("Deidentify file response: " + deidentifyFileResponse.toString()); - } catch (SkyflowException e) { - System.err.println("Error occurred during deidentify file: "); - e.printStackTrace(); - } - } -} - -``` - -Sample response: - -```json -{ - "file": { - "name": "deidentified.txt", - "size": 33, - "type": "", - "lastModified": 1751355183039 - }, - "fileBase64": "bXkgY2FyZCBudW1iZXIgaXMgW0NSRURJVF", - "type": "redacted_file", - "extension": "txt", - "wordCount": 11, - "charCount": 61, - "sizeInKb": 0, - "entities": [ - { - "file": "bmFtZTogW05BTUVfMV0gCm==", - "type": "entities", - "extension": "json" - } ], - "runId": "undefined", - "status": "success" -} - -``` - -**Supported file types:** -- Documents: `doc`, `docx`, `pdf` -- PDFs: `pdf` -- Images: `bmp`, `jpeg`, `jpg`, `png`, `tif`, `tiff` -- Structured text: `json`, `xml` -- Spreadsheets: `csv`, `xls`, `xlsx` -- Presentations: `ppt`, `pptx` -- Audio: `mp3`, `wav` - -**Note:** -- Transformations cannot be applied to Documents, Images, or PDFs file formats. - -- The `waitTime` option must be ≤ 64 seconds; otherwise, an error is thrown. - -- If the API takes more than 64 seconds to process the file, it will return only the run ID in the response. - -Sample response (when the API takes more than 64 seconds): -```json -{ - "file": null, - "fileBase64": null, - "type": null, - "extension": null, - "wordCount": null, - "charCount": null, - "sizeInKb": null, - "durationInSeconds": null, - "pageCount": null, - "slideCount": null, - "entities": null, - "runId": "1273a8c6-c498-4293-a9d6-389864cd3a44", - "status": "IN_PROGRESS", - "errors": null -} -``` - -## Get run: -To retrieve the results of a previously started file `deidentification operation`, use the `getDetectRun` method. -The `GetDetectRunRequest` class is initialized with the `runId` returned from a prior deidentifyFile call. -This method allows you to fetch the final results of the file processing operation once they are available. - -### Construct an get run request - -```java -import com.skyflow.errors.SkyflowException; -import com.skyflow.vault.detect.DeidentifyFileResponse; -import com.skyflow.vault.detect.GetDetectRunRequest; - -/** - * Skyflow Get Detect Run Example - */ - -public class GetDetectRunSchema { - - public static void main(String[] args) { - try { - // Step 1: Initialise the Skyflow client by configuring the credentials & vault config. - - // Step 2: Create a get detect run request - GetDetectRunRequest getDetectRunRequest = GetDetectRunRequest.builder() - .runId("") // Replace with the runId from deidentifyFile call - .build(); - - // Step 3: Call getDetectRun to poll for file processing results - // Replace with your actual vault ID - DeidentifyFileResponse deidentifyFileResponse = skyflowClient.detect("").getDetectRun(getDetectRunRequest); - System.out.println("Get Detect Run Response: " + deidentifyFileResponse); - } catch (SkyflowException e) { - System.err.println("Error occurred during get detect run: "); - e.printStackTrace(); - } - } -} - -``` - -## An [example](https://github.com/skyflowapi/skyflow-java/blob/beta-release/25.6.2/samples/src/main/java/com/example/detect/GetDetectRunExample.java) of get run -```java -import com.skyflow.config.Credentials; -import com.skyflow.config.VaultConfig; -import com.skyflow.enums.Env; -import com.skyflow.enums.LogLevel; -import com.skyflow.errors.SkyflowException; -import com.skyflow.vault.detect.DeidentifyFileResponse; -import com.skyflow.vault.detect.GetDetectRunRequest; - -/** - * Skyflow Get Detect Run Example - *

- * This example demonstrates how to: - * 1. Configure credentials - * 2. Set up vault configuration - * 3. Create a get detect run request - * 4. Call getDetectRun to poll for file processing results - * 5. Handle response and errors - */ -public class GetDetectRunExample { - public static void main(String[] args) throws SkyflowException { - // Step 1: Initialise the Skyflow client by configuring the credentials & vault config. - try { - - // Step 2: Create a get detect run request - GetDetectRunRequest getDetectRunRequest = GetDetectRunRequest.builder() - .runId("e0038196-4a20-422b-bad7-e0477117f9bb") // Replace with the runId from deidentifyFile call - .build(); - - // Step 3: Call getDetectRun to poll for file processing results - // Replace `9f27764a10f7946fe56b3258e117` with the acutal vault id - DeidentifyFileResponse deidentifyFileResponse = skyflowClient.detect("9f27764a10f7946fe56b3258e117").getDetectRun(getDetectRunRequest); - System.out.println("Get Detect Run Response: " + deidentifyFileResponse); - } catch (SkyflowException e) { - System.err.println("Error occurred during get detect run: "); - e.printStackTrace(); - } - } -} -``` - -Sample Response: - -```json -{ - "file": "bmFtZTogW05BTET0JfMV0K", - "type": "redacted_file", - "extension": "txt", - "wordCount": 11, - "charCount": 61, - "sizeInKb": 0.0, - "entities": [ + "errors": [ { - "file": "gW05BTUVfMV0gCmNhcmQ0K", - "type": "entities", - "extension": "json" - } - ], - "runId": "e0038196-4a20-422b-bad7-e0477117f9bb", - "status": "success" -} - -``` - -# Connections - -Skyflow Connections is a gateway service that uses tokenization to securely send and receive data between your systems and first- or third-party services. The [connections](https://github.com/skyflowapi/skyflow-java/tree/main/src/main/java/com/skyflow/vault/connection) module invokes both inbound and/or outbound connections. - -- **Inbound connections**: Act as intermediaries between your client and server, tokenizing sensitive data before it reaches your backend, ensuring downstream services handle only tokenized data. -- **Outbound connections**: Enable secure extraction of data from the vault and transfer it to third-party services via your backend server, such as processing checkout or card issuance flows. - -## Invoke a connection - -To invoke a connection, use the `invoke` method of the Skyflow client. - -### Construct an invoke connection request - -```java -import com.skyflow.enums.RequestMethod; -import com.skyflow.errors.SkyflowException; -import com.skyflow.vault.connection.InvokeConnectionRequest; -import com.skyflow.vault.connection.InvokeConnectionResponse; - -import java.util.HashMap; -import java.util.Map; - -/** - * This example demonstrates how to invoke an external connection using the Skyflow SDK, along with corresponding InvokeConnectionRequest schema. - * - */ -public class InvokeConnectionSchema { - public static void main(String[] args) { - try { - // Initialize Skyflow client - // Step 1: Define the request body parameters - // These are the values you want to send in the request body - Map requestBody = new HashMap<>(); - requestBody.put("", ""); - requestBody.put("", ""); - - // Step 2: Define the request headers - // Add any required headers that need to be sent with the request - Map requestHeaders = new HashMap<>(); - requestHeaders.put("", ""); - requestHeaders.put("", ""); - - // Step 3: Define the path parameters - // Path parameters are part of the URL and typically used in RESTful APIs - Map pathParams = new HashMap<>(); - pathParams.put("", ""); - pathParams.put("", ""); - - // Step 4: Define the query parameters - // Query parameters are included in the URL after a '?' and are used to filter or modify the response - Map queryParams = new HashMap<>(); - queryParams.put("", ""); - queryParams.put("", ""); - - // Step 5: Build the InvokeConnectionRequest using the provided parameters - InvokeConnectionRequest invokeConnectionRequest = InvokeConnectionRequest.builder() - .method(RequestMethod.POST) // The HTTP method to use for the request (POST in this case) - .requestBody(requestBody) // The body of the request - .requestHeaders(requestHeaders) // The headers to include in the request - .pathParams(pathParams) // The path parameters for the URL - .queryParams(queryParams) // The query parameters to append to the URL - .build(); - - // Step 6: Invoke the connection using the request - // Replace "" with the actual connection ID you are using - InvokeConnectionResponse invokeConnectionResponse = skyflowClient.connection("").invoke(invokeConnectionRequest); - - // Step 7: Print the response from the invoked connection - // This response contains the result of the request sent to the external system - System.out.println(invokeConnectionResponse); - - } catch (SkyflowException e) { - // Step 8: Handle any exceptions that occur during the connection invocation - System.out.println("Error occurred: "); - e.printStackTrace(); // Print the exception stack trace for debugging - } - } -} -``` - -`method` supports the following methods: - -- GET -- POST -- PUT -- PATCH -- DELETE - -**pathParams, queryParams, requestHeader, requestBody** are the JSON objects represented as HashMaps, that will be sent through the connection integration url. - -### An [example](https://github.com/skyflowapi/skyflow-java/blob/main/samples/src/main/java/com/example/connection/InvokeConnectionExample.java) of invokeConnection - -```java -import com.skyflow.Skyflow; -import com.skyflow.config.ConnectionConfig; -import com.skyflow.config.Credentials; -import com.skyflow.enums.LogLevel; -import com.skyflow.enums.RequestMethod; -import com.skyflow.errors.SkyflowException; -import com.skyflow.vault.connection.InvokeConnectionRequest; -import com.skyflow.vault.connection.InvokeConnectionResponse; - -import java.util.HashMap; -import java.util.Map; - -/** - * This example demonstrates how to invoke an external connection using the Skyflow SDK. - * It configures a connection, sets up the request, and sends a POST request to the external service. - * - * 1. Initialize Skyflow client with connection details. - * 2. Define the request body, headers, and method. - * 3. Execute the connection request. - * 4. Print the response from the invoked connection. - */ -public class InvokeConnectionExample { - public static void main(String[] args) { - try { - // Initialize Skyflow client - // Step 1: Set up credentials and connection configuration - // Load credentials from a JSON file (you need to provide the correct path) - Credentials credentials = new Credentials(); - credentials.setPath("/path/to/credentials.json"); - - // Define the connection configuration (URL and credentials) - ConnectionConfig connectionConfig = new ConnectionConfig(); - connectionConfig.setConnectionId(""); // Replace with actual connection ID - connectionConfig.setConnectionUrl("https://connection.url.com"); // Replace with actual connection URL - connectionConfig.setCredentials(credentials); // Set credentials for the connection - - // Initialize the Skyflow client with the connection configuration - Skyflow skyflowClient = Skyflow.builder() - .setLogLevel(LogLevel.DEBUG) // Set log level to DEBUG for detailed logs - .addConnectionConfig(connectionConfig) // Add connection configuration to client - .build(); // Build the Skyflow client instance - - // Step 2: Define the request body and headers - // Map for request body parameters - Map requestBody = new HashMap<>(); - requestBody.put("card_number", "4337-1696-5866-0865"); // Example card number - requestBody.put("ssn", "524-41-4248"); // Example SSN - - // Map for request headers - Map requestHeaders = new HashMap<>(); - requestHeaders.put("Content-Type", "application/json"); // Set content type for the request - - // Step 3: Build the InvokeConnectionRequest with required parameters - // Set HTTP method to POST, include the request body and headers - InvokeConnectionRequest invokeConnectionRequest = InvokeConnectionRequest.builder() - .method(RequestMethod.POST) // HTTP POST method - .requestBody(requestBody) // Add request body parameters - .requestHeaders(requestHeaders) // Add headers - .build(); // Build the request - - // Step 4: Invoke the connection and capture the response - // Replace "" with the actual connection ID - InvokeConnectionResponse invokeConnectionResponse = skyflowClient.connection("").invoke(invokeConnectionRequest); - - // Step 5: Print the response from the connection invocation - System.out.println(invokeConnectionResponse); // Print the response to the console - - } catch (SkyflowException e) { - // Step 6: Handle any exceptions that occur during the connection invocation - System.out.println("Error occurred: "); - e.printStackTrace(); // Print the exception stack trace for debugging - } + "index": 1, + "code": 404, + "error": "Detokenize failed. Token 6ffb412b-a79d is invalid. Specify a valid token.", } -} -``` - -Sample response: - -```json -{ - "data": { - "card_number": "4337-1696-5866-0865", - "ssn": "524-41-4248" - }, - "metadata": { - "requestId": "4a3453b5-7aa4-4373-98d7-cf102b1f6f97" - } + ] } ``` @@ -2606,11 +688,11 @@ This section covers methods for generating and managing tokens to authenticate A ## Generate a bearer token -The [Service Account](https://github.com/skyflowapi/skyflow-java/tree/v2/src/main/java/com/skyflow/serviceaccount/util) Java module generates service account tokens using a service account credentials file, which is provided when a service account is created. The tokens generated by this module are valid for 60 minutes and can be used to make API calls to the [Data](https://docs.skyflow.com/record/) and [Management](https://docs.skyflow.com/management/) APIs, depending on the permissions assigned to the service account. +The [Service Account](https://github.com/skyflowapi/skyflow-java/tree/v3/common/src/main/java/com/skyflow/serviceaccount/util) Java module generates service account tokens using a service account credentials file, which is provided when a service account is created. The tokens generated by this module are valid for 60 minutes and can be used to make API calls to the [Data](https://docs.skyflow.com/api/data/) and [Management](https://docs.skyflow.com/management/) APIs, depending on the permissions assigned to the service account. The `BearerToken` utility class generates bearer tokens using a credentials JSON file. Alternatively, you can pass the credentials as a string. -[Example](https://github.com/skyflowapi/skyflow-java/blob/main/samples/src/main/java/com/example/serviceaccount/BearerTokenGenerationExample.java): +Example: ```java /** @@ -2679,7 +761,7 @@ public class BearerTokenGenerationExample { A service account with the `context_id` identifier generates bearer tokens containing context information, represented as a JWT claim in a Skyflow-generated bearer token. Tokens generated from such service accounts include a `context_identifier` claim, are valid for 60 minutes, and can be used to make API calls to the Data and Management APIs, depending on the service account's permissions. -[Example](https://github.com/skyflowapi/skyflow-java/blob/main/samples/src/main/java/com/example/serviceaccount/BearerTokenGenerationWithContextExample.java): +Example: ```java import com.skyflow.errors.SkyflowException; @@ -2747,7 +829,7 @@ public class BearerTokenGenerationWithContextExample { A service account with multiple roles can generate bearer tokens with access limited to a specific role by specifying the appropriate `roleID`. This can be used to limit access to specific roles for services with multiple responsibilities, such as segregating access for billing and analytics. The generated bearer tokens are valid for 60 minutes and can only execute operations permitted by the permissions associated with the designated role. -[Example](https://github.com/skyflowapi/skyflow-java/blob/main/samples/src/main/java/com/example/serviceaccount/ScopedTokenGenerationExample.java): +Example: ```java import com.skyflow.errors.SkyflowException; @@ -2798,7 +880,6 @@ Notes: - You can pass either the file path of a service account key credentials file or the service account key credentials as a string to the `setCredentials` method of the `BearerTokenBuilder` class. - If both a file path and a string are provided, the last method used takes precedence. -- To generate multiple bearer tokens concurrently using threads, refer to the following [example](https://github.com/skyflowapi/skyflow-java/blob/main/samples/src/main/java/com/example/serviceaccount/BearerTokenGenerationUsingThreadsExample.java). ## Generate Signed Data Tokens @@ -2807,7 +888,7 @@ with the private key of the service account credentials, which adds an additiona be detokenized by passing the signed data token and a bearer token generated from service account credentials. The service account must have appropriate permissions and context to detokenize the signed data tokens. -[Example](https://github.com/skyflowapi/skyflow-java/blob/main/samples/src/main/java/com/example/serviceaccount/SignedTokenGenerationExample.java): +Example: ```java import com.skyflow.errors.SkyflowException; @@ -2887,7 +968,7 @@ message: Authentication failed. Bearer token is expired. Use a valid bearer toke If you encounter this kind of error, retry the request. During the retry, the SDK detects that the previous bearer token has expired and generates a new one for the current and subsequent requests. -#### [Example](https://github.com/skyflowapi/skyflow-java/blob/v2/samples/src/main/java/com/example/serviceaccount/BearerTokenExpiryExample.java): +#### Example: ```java package com.example.serviceaccount; @@ -2965,8 +1046,6 @@ public class DetokenizeExample { // Building a detokenization request with the token list and configuration DetokenizeRequest detokenizeRequest = DetokenizeRequest.builder() .tokens(tokenList) // Adding tokens to the request - .continueOnError(false) // Stop on error - .redactionType(RedactionType.PLAIN_TEXT) // Redaction type (e.g., PLAIN_TEXT) .build(); // Sending the detokenization request and receiving the response @@ -3058,4 +1137,4 @@ public class ChangeLogLevel { # Reporting a Vulnerability -If you discover a potential security issue in this project, please reach out to us at **security@skyflow.com**. Please do not create public GitHub issues or Pull Requests, as malicious actors could potentially view them. +If you discover a potential security issue in this project, please reach out to us at **security@skyflow.com**. Please do not create public GitHub issues or Pull Requests, as malicious actors could potentially view them. \ No newline at end of file diff --git a/Rule/gitleaks.toml b/Rule/gitleaks.toml new file mode 100644 index 00000000..e127f827 --- /dev/null +++ b/Rule/gitleaks.toml @@ -0,0 +1,3137 @@ +# This file has been auto-generated. Do not edit manually. +# If you would like to contribute new rules, please use +# cmd/generate/config/main.go and follow the contributing guidelines +# at https://github.com/gitleaks/gitleaks/blob/master/CONTRIBUTING.md +# +# How the hell does secret scanning work? Read this: +# https://lookingatcomputer.substack.com/p/regex-is-almost-all-you-need +# +# This is the default gitleaks configuration file. +# Rules and allowlists are defined within this file. +# Rules instruct gitleaks on what should be considered a secret. +# Allowlists instruct gitleaks on what is allowed, i.e. not a secret. + +title = "gitleaks config" + +[allowlist] +description = "global allow lists" +regexes = [ + '''(?i)^true|false|null$''', + '''^(?i:a+|b+|c+|d+|e+|f+|g+|h+|i+|j+|k+|l+|m+|n+|o+|p+|q+|r+|s+|t+|u+|v+|w+|x+|y+|z+|\*+|\.+)$''', + '''^\$(?:\d+|{\d+})$''', + '''^\$(?:[A-Z_]+|[a-z_]+)$''', + '''^\${(?:[A-Z_]+|[a-z_]+)}$''', + '''^\{\{[ \t]*[\w ().|]+[ \t]*}}$''', + '''^\$\{\{[ \t]*(?:(?:env|github|secrets|vars)(?:\.[A-Za-z]\w+)+[\w "'&./=|]*)[ \t]*}}$''', + '''^%(?:[A-Z_]+|[a-z_]+)%$''', + '''^%[+\-# 0]?[bcdeEfFgGoOpqstTUvxX]$''', + '''^\{\d{0,2}}$''', + '''^@(?:[A-Z_]+|[a-z_]+)@$''', + '''^/Users/(?i)[a-z0-9]+/[\w .-/]+$''', + '''^/(?:bin|etc|home|opt|tmp|usr|var)/[\w ./-]+$''', +] +paths = [ + '''gitleaks\.toml''', + '''(?i)\.(?:bmp|gif|jpe?g|png|svg|tiff?)$''', + '''(?i)\.(?:eot|[ot]tf|woff2?)$''', + '''(?i)\.(?:docx?|xlsx?|pdf|bin|socket|vsidx|v2|suo|wsuo|.dll|pdb|exe|gltf|zip)$''', + '''go\.(?:mod|sum|work(?:\.sum)?)$''', + '''(?:^|/)vendor/modules\.txt$''', + '''(?:^|/)vendor/(?:github\.com|golang\.org/x|google\.golang\.org|gopkg\.in|istio\.io|k8s\.io|sigs\.k8s\.io)(?:/.*)?$''', + '''(?:^|/)gradlew(?:\.bat)?$''', + '''(?:^|/)gradle\.lockfile$''', + '''(?:^|/)mvnw(?:\.cmd)?$''', + '''(?:^|/)\.mvn/wrapper/MavenWrapperDownloader\.java$''', + '''(?:^|/)node_modules(?:/.*)?$''', + '''(?:^|/)(?:deno\.lock|npm-shrinkwrap\.json|package-lock\.json|pnpm-lock\.yaml|yarn\.lock)$''', + '''(?:^|/)bower_components(?:/.*)?$''', + '''(?:^|/)(?:angular|bootstrap|jquery(?:-?ui)?|plotly|swagger-?ui)[a-zA-Z0-9.-]*(?:\.min)?\.js(?:\.map)?$''', + '''(?:^|/)javascript\.json$''', + '''(?:^|/)(?:Pipfile|poetry)\.lock$''', + '''(?i)(?:^|/)(?:v?env|virtualenv)/lib(?:64)?(?:/.*)?$''', + '''(?i)(?:^|/)(?:lib(?:64)?/python[23](?:\.\d{1,2})+|python/[23](?:\.\d{1,2})+/lib(?:64)?)(?:/.*)?$''', + '''(?i)(?:^|/)[a-z0-9_.]+-[0-9.]+\.dist-info(?:/.+)?$''', + '''(?:^|/)vendor/(?:bundle|ruby)(?:/.*?)?$''', + '''\.gem$''', + '''verification-metadata\.xml''', + '''Database.refactorlog''', +] +stopwords = [ + "abcdefghijklmnopqrstuvwxyz", + "014df517-39d1-4453-b7b3-9930c563627c", +] + +[[rules]] +id = "1password-service-account-token" +description = "Uncovered a possible 1Password service account token, potentially compromising access to secrets in vaults." +regex = '''ops_eyJ[a-zA-Z0-9+/]{250,}={0,3}''' +entropy = 4 +keywords = ["ops_"] + +[[rules]] +id = "adafruit-api-key" +description = "Identified a potential Adafruit API Key, which could lead to unauthorized access to Adafruit services and sensitive data exposure." +regex = '''(?i)[\w.-]{0,50}?(?:adafruit)(?:[ \t\w.-]{0,20})[\s'"]{0,3}(?:=|>|:{1,3}=|\|\||:|=>|\?=|,)[\x60'"\s=]{0,5}([a-z0-9_-]{32})(?:[\x60'"\s;]|\\[nr]|$)''' +keywords = ["adafruit"] + +[[rules]] +id = "adobe-client-id" +description = "Detected a pattern that resembles an Adobe OAuth Web Client ID, posing a risk of compromised Adobe integrations and data breaches." +regex = '''(?i)[\w.-]{0,50}?(?:adobe)(?:[ \t\w.-]{0,20})[\s'"]{0,3}(?:=|>|:{1,3}=|\|\||:|=>|\?=|,)[\x60'"\s=]{0,5}([a-f0-9]{32})(?:[\x60'"\s;]|\\[nr]|$)''' +entropy = 2 +keywords = ["adobe"] + +[[rules]] +id = "adobe-client-secret" +description = "Discovered a potential Adobe Client Secret, which, if exposed, could allow unauthorized Adobe service access and data manipulation." +regex = '''\b(p8e-(?i)[a-z0-9]{32})(?:[\x60'"\s;]|\\[nr]|$)''' +entropy = 2 +keywords = ["p8e-"] + +[[rules]] +id = "age-secret-key" +description = "Discovered a potential Age encryption tool secret key, risking data decryption and unauthorized access to sensitive information." +regex = '''AGE-SECRET-KEY-1[QPZRY9X8GF2TVDW0S3JN54KHCE6MUA7L]{58}''' +keywords = ["age-secret-key-1"] + +[[rules]] +id = "airtable-api-key" +description = "Uncovered a possible Airtable API Key, potentially compromising database access and leading to data leakage or alteration." +regex = '''(?i)[\w.-]{0,50}?(?:airtable)(?:[ \t\w.-]{0,20})[\s'"]{0,3}(?:=|>|:{1,3}=|\|\||:|=>|\?=|,)[\x60'"\s=]{0,5}([a-z0-9]{17})(?:[\x60'"\s;]|\\[nr]|$)''' +keywords = ["airtable"] + +[[rules]] +id = "algolia-api-key" +description = "Identified an Algolia API Key, which could result in unauthorized search operations and data exposure on Algolia-managed platforms." +regex = '''(?i)[\w.-]{0,50}?(?:algolia)(?:[ \t\w.-]{0,20})[\s'"]{0,3}(?:=|>|:{1,3}=|\|\||:|=>|\?=|,)[\x60'"\s=]{0,5}([a-z0-9]{32})(?:[\x60'"\s;]|\\[nr]|$)''' +keywords = ["algolia"] + +[[rules]] +id = "alibaba-access-key-id" +description = "Detected an Alibaba Cloud AccessKey ID, posing a risk of unauthorized cloud resource access and potential data compromise." +regex = '''\b(LTAI(?i)[a-z0-9]{20})(?:[\x60'"\s;]|\\[nr]|$)''' +entropy = 2 +keywords = ["ltai"] + +[[rules]] +id = "alibaba-secret-key" +description = "Discovered a potential Alibaba Cloud Secret Key, potentially allowing unauthorized operations and data access within Alibaba Cloud." +regex = '''(?i)[\w.-]{0,50}?(?:alibaba)(?:[ \t\w.-]{0,20})[\s'"]{0,3}(?:=|>|:{1,3}=|\|\||:|=>|\?=|,)[\x60'"\s=]{0,5}([a-z0-9]{30})(?:[\x60'"\s;]|\\[nr]|$)''' +entropy = 2 +keywords = ["alibaba"] + +[[rules]] +id = "asana-client-id" +description = "Discovered a potential Asana Client ID, risking unauthorized access to Asana projects and sensitive task information." +regex = '''(?i)[\w.-]{0,50}?(?:asana)(?:[ \t\w.-]{0,20})[\s'"]{0,3}(?:=|>|:{1,3}=|\|\||:|=>|\?=|,)[\x60'"\s=]{0,5}([0-9]{16})(?:[\x60'"\s;]|\\[nr]|$)''' +keywords = ["asana"] + +[[rules]] +id = "asana-client-secret" +description = "Identified an Asana Client Secret, which could lead to compromised project management integrity and unauthorized access." +regex = '''(?i)[\w.-]{0,50}?(?:asana)(?:[ \t\w.-]{0,20})[\s'"]{0,3}(?:=|>|:{1,3}=|\|\||:|=>|\?=|,)[\x60'"\s=]{0,5}([a-z0-9]{32})(?:[\x60'"\s;]|\\[nr]|$)''' +keywords = ["asana"] + +[[rules]] +id = "atlassian-api-token" +description = "Detected an Atlassian API token, posing a threat to project management and collaboration tool security and data confidentiality." +regex = '''[\w.-]{0,50}?(?i:[\w.-]{0,50}?(?:atlassian|confluence|jira)(?:[ \t\w.-]{0,20})[\s'"]{0,3})(?:=|>|:{1,3}=|\|\||:|=>|\?=|,)[\x60'"\s=]{0,5}([a-zA-Z0-9]{24})(?:[\x60'"\s;]|\\[nr]|$)|\b(ATATT3[A-Za-z0-9_\-=]{186})(?:[\x60'"\s;]|\\[nr]|$)''' +entropy = 3.5 +keywords = [ + "atlassian", + "confluence", + "jira", + "atatt3", +] + +[[rules]] +id = "authress-service-client-access-key" +description = "Uncovered a possible Authress Service Client Access Key, which may compromise access control services and sensitive data." +regex = '''\b((?:sc|ext|scauth|authress)_(?i)[a-z0-9]{5,30}\.[a-z0-9]{4,6}\.(?-i:acc)[_-][a-z0-9-]{10,32}\.[a-z0-9+/_=-]{30,120})(?:[\x60'"\s;]|\\[nr]|$)''' +entropy = 2 +keywords = [ + "sc_", + "ext_", + "scauth_", + "authress_", +] + +[[rules]] +id = "aws-access-token" +description = "Identified a pattern that may indicate AWS credentials, risking unauthorized cloud resource access and data breaches on AWS platforms." +regex = '''\b((?:A3T[A-Z0-9]|AKIA|ASIA|ABIA|ACCA)[A-Z0-9]{16})\b''' +entropy = 3 +keywords = [ + "a3t", + "akia", + "asia", + "abia", + "acca", +] +[[rules.allowlists]] +regexes = [ + '''.+EXAMPLE$''', +] + +[[rules]] +id = "azure-ad-client-secret" +description = "Azure AD Client Secret" +regex = '''(?:^|[\\'"\x60\s>=:(,)])([a-zA-Z0-9_~.]{3}\dQ~[a-zA-Z0-9_~.-]{31,34})(?:$|[\\'"\x60\s<),])''' +entropy = 3 +keywords = ["q~"] + +[[rules]] +id = "beamer-api-token" +description = "Detected a Beamer API token, potentially compromising content management and exposing sensitive notifications and updates." +regex = '''(?i)[\w.-]{0,50}?(?:beamer)(?:[ \t\w.-]{0,20})[\s'"]{0,3}(?:=|>|:{1,3}=|\|\||:|=>|\?=|,)[\x60'"\s=]{0,5}(b_[a-z0-9=_\-]{44})(?:[\x60'"\s;]|\\[nr]|$)''' +keywords = ["beamer"] + +[[rules]] +id = "bitbucket-client-id" +description = "Discovered a potential Bitbucket Client ID, risking unauthorized repository access and potential codebase exposure." +regex = '''(?i)[\w.-]{0,50}?(?:bitbucket)(?:[ \t\w.-]{0,20})[\s'"]{0,3}(?:=|>|:{1,3}=|\|\||:|=>|\?=|,)[\x60'"\s=]{0,5}([a-z0-9]{32})(?:[\x60'"\s;]|\\[nr]|$)''' +keywords = ["bitbucket"] + +[[rules]] +id = "bitbucket-client-secret" +description = "Discovered a potential Bitbucket Client Secret, posing a risk of compromised code repositories and unauthorized access." +regex = '''(?i)[\w.-]{0,50}?(?:bitbucket)(?:[ \t\w.-]{0,20})[\s'"]{0,3}(?:=|>|:{1,3}=|\|\||:|=>|\?=|,)[\x60'"\s=]{0,5}([a-z0-9=_\-]{64})(?:[\x60'"\s;]|\\[nr]|$)''' +keywords = ["bitbucket"] + +[[rules]] +id = "bittrex-access-key" +description = "Identified a Bittrex Access Key, which could lead to unauthorized access to cryptocurrency trading accounts and financial loss." +regex = '''(?i)[\w.-]{0,50}?(?:bittrex)(?:[ \t\w.-]{0,20})[\s'"]{0,3}(?:=|>|:{1,3}=|\|\||:|=>|\?=|,)[\x60'"\s=]{0,5}([a-z0-9]{32})(?:[\x60'"\s;]|\\[nr]|$)''' +keywords = ["bittrex"] + +[[rules]] +id = "bittrex-secret-key" +description = "Detected a Bittrex Secret Key, potentially compromising cryptocurrency transactions and financial security." +regex = '''(?i)[\w.-]{0,50}?(?:bittrex)(?:[ \t\w.-]{0,20})[\s'"]{0,3}(?:=|>|:{1,3}=|\|\||:|=>|\?=|,)[\x60'"\s=]{0,5}([a-z0-9]{32})(?:[\x60'"\s;]|\\[nr]|$)''' +keywords = ["bittrex"] + +[[rules]] +id = "cisco-meraki-api-key" +description = "Cisco Meraki is a cloud-managed IT solution that provides networking, security, and device management through an easy-to-use interface." +regex = '''[\w.-]{0,50}?(?i:[\w.-]{0,50}?(?:(?-i:[Mm]eraki|MERAKI))(?:[ \t\w.-]{0,20})[\s'"]{0,3})(?:=|>|:{1,3}=|\|\||:|=>|\?=|,)[\x60'"\s=]{0,5}([0-9a-f]{40})(?:[\x60'"\s;]|\\[nr]|$)''' +entropy = 3 +keywords = ["meraki"] + +[[rules]] +id = "clojars-api-token" +description = "Uncovered a possible Clojars API token, risking unauthorized access to Clojure libraries and potential code manipulation." +regex = '''(?i)CLOJARS_[a-z0-9]{60}''' +entropy = 2 +keywords = ["clojars_"] + +[[rules]] +id = "cloudflare-api-key" +description = "Detected a Cloudflare API Key, potentially compromising cloud application deployments and operational security." +regex = '''(?i)[\w.-]{0,50}?(?:cloudflare)(?:[ \t\w.-]{0,20})[\s'"]{0,3}(?:=|>|:{1,3}=|\|\||:|=>|\?=|,)[\x60'"\s=]{0,5}([a-z0-9_-]{40})(?:[\x60'"\s;]|\\[nr]|$)''' +entropy = 2 +keywords = ["cloudflare"] + +[[rules]] +id = "cloudflare-global-api-key" +description = "Detected a Cloudflare Global API Key, potentially compromising cloud application deployments and operational security." +regex = '''(?i)[\w.-]{0,50}?(?:cloudflare)(?:[ \t\w.-]{0,20})[\s'"]{0,3}(?:=|>|:{1,3}=|\|\||:|=>|\?=|,)[\x60'"\s=]{0,5}([a-f0-9]{37})(?:[\x60'"\s;]|\\[nr]|$)''' +entropy = 2 +keywords = ["cloudflare"] + +[[rules]] +id = "cloudflare-origin-ca-key" +description = "Detected a Cloudflare Origin CA Key, potentially compromising cloud application deployments and operational security." +regex = '''\b(v1\.0-[a-f0-9]{24}-[a-f0-9]{146})(?:[\x60'"\s;]|\\[nr]|$)''' +entropy = 2 +keywords = [ + "cloudflare", + "v1.0-", +] + +[[rules]] +id = "codecov-access-token" +description = "Found a pattern resembling a Codecov Access Token, posing a risk of unauthorized access to code coverage reports and sensitive data." +regex = '''(?i)[\w.-]{0,50}?(?:codecov)(?:[ \t\w.-]{0,20})[\s'"]{0,3}(?:=|>|:{1,3}=|\|\||:|=>|\?=|,)[\x60'"\s=]{0,5}([a-z0-9]{32})(?:[\x60'"\s;]|\\[nr]|$)''' +keywords = ["codecov"] + +[[rules]] +id = "cohere-api-token" +description = "Identified a Cohere Token, posing a risk of unauthorized access to AI services and data manipulation." +regex = '''[\w.-]{0,50}?(?i:[\w.-]{0,50}?(?:cohere|CO_API_KEY)(?:[ \t\w.-]{0,20})[\s'"]{0,3})(?:=|>|:{1,3}=|\|\||:|=>|\?=|,)[\x60'"\s=]{0,5}([a-zA-Z0-9]{40})(?:[\x60'"\s;]|\\[nr]|$)''' +entropy = 4 +keywords = [ + "cohere", + "co_api_key", +] + +[[rules]] +id = "coinbase-access-token" +description = "Detected a Coinbase Access Token, posing a risk of unauthorized access to cryptocurrency accounts and financial transactions." +regex = '''(?i)[\w.-]{0,50}?(?:coinbase)(?:[ \t\w.-]{0,20})[\s'"]{0,3}(?:=|>|:{1,3}=|\|\||:|=>|\?=|,)[\x60'"\s=]{0,5}([a-z0-9_-]{64})(?:[\x60'"\s;]|\\[nr]|$)''' +keywords = ["coinbase"] + +[[rules]] +id = "confluent-access-token" +description = "Identified a Confluent Access Token, which could compromise access to streaming data platforms and sensitive data flow." +regex = '''(?i)[\w.-]{0,50}?(?:confluent)(?:[ \t\w.-]{0,20})[\s'"]{0,3}(?:=|>|:{1,3}=|\|\||:|=>|\?=|,)[\x60'"\s=]{0,5}([a-z0-9]{16})(?:[\x60'"\s;]|\\[nr]|$)''' +keywords = ["confluent"] + +[[rules]] +id = "confluent-secret-key" +description = "Found a Confluent Secret Key, potentially risking unauthorized operations and data access within Confluent services." +regex = '''(?i)[\w.-]{0,50}?(?:confluent)(?:[ \t\w.-]{0,20})[\s'"]{0,3}(?:=|>|:{1,3}=|\|\||:|=>|\?=|,)[\x60'"\s=]{0,5}([a-z0-9]{64})(?:[\x60'"\s;]|\\[nr]|$)''' +keywords = ["confluent"] + +[[rules]] +id = "contentful-delivery-api-token" +description = "Discovered a Contentful delivery API token, posing a risk to content management systems and data integrity." +regex = '''(?i)[\w.-]{0,50}?(?:contentful)(?:[ \t\w.-]{0,20})[\s'"]{0,3}(?:=|>|:{1,3}=|\|\||:|=>|\?=|,)[\x60'"\s=]{0,5}([a-z0-9=_\-]{43})(?:[\x60'"\s;]|\\[nr]|$)''' +keywords = ["contentful"] + +[[rules]] +id = "curl-auth-header" +description = "Discovered a potential authorization token provided in a curl command header, which could compromise the curl accessed resource." +regex = '''\bcurl\b(?:.*?|.*?(?:[\r\n]{1,2}.*?){1,5})[ \t\n\r](?:-H|--header)(?:=|[ \t]{0,5})(?:"(?i)(?:Authorization:[ \t]{0,5}(?:Basic[ \t]([a-z0-9+/]{8,}={0,3})|(?:Bearer|(?:Api-)?Token)[ \t]([\w=~@.+/-]{8,})|([\w=~@.+/-]{8,}))|(?:(?:X-(?:[a-z]+-)?)?(?:Api-?)?(?:Key|Token)):[ \t]{0,5}([\w=~@.+/-]{8,}))"|'(?i)(?:Authorization:[ \t]{0,5}(?:Basic[ \t]([a-z0-9+/]{8,}={0,3})|(?:Bearer|(?:Api-)?Token)[ \t]([\w=~@.+/-]{8,})|([\w=~@.+/-]{8,}))|(?:(?:X-(?:[a-z]+-)?)?(?:Api-?)?(?:Key|Token)):[ \t]{0,5}([\w=~@.+/-]{8,}))')(?:\B|\s|\z)''' +entropy = 2.75 +keywords = ["curl"] + +[[rules]] +id = "curl-auth-user" +description = "Discovered a potential basic authorization token provided in a curl command, which could compromise the curl accessed resource." +regex = '''\bcurl\b(?:.*|.*(?:[\r\n]{1,2}.*){1,5})[ \t\n\r](?:-u|--user)(?:=|[ \t]{0,5})("(:[^"]{3,}|[^:"]{3,}:|[^:"]{3,}:[^"]{3,})"|'([^:']{3,}:[^']{3,})'|((?:"[^"]{3,}"|'[^']{3,}'|[\w$@.-]+):(?:"[^"]{3,}"|'[^']{3,}'|[\w${}@.-]+)))(?:\s|\z)''' +entropy = 2 +keywords = ["curl"] +[[rules.allowlists]] +regexes = [ + '''[^:]+:(?:change(?:it|me)|pass(?:word)?|pwd|test|token|\*+|x+)''', + '''['"]?<[^>]+>['"]?:['"]?<[^>]+>|<[^:]+:[^>]+>['"]?''', + '''[^:]+:\[[^]]+]''', + '''['"]?[^:]+['"]?:['"]?\$(?:\d|\w+|\{(?:\d|\w+)})['"]?''', + '''\$\([^)]+\):\$\([^)]+\)''', + '''['"]?\$?{{[^}]+}}['"]?:['"]?\$?{{[^}]+}}['"]?''', +] + +[[rules]] +id = "databricks-api-token" +description = "Uncovered a Databricks API token, which may compromise big data analytics platforms and sensitive data processing." +regex = '''\b(dapi[a-f0-9]{32}(?:-\d)?)(?:[\x60'"\s;]|\\[nr]|$)''' +entropy = 3 +keywords = ["dapi"] + +[[rules]] +id = "datadog-access-token" +description = "Detected a Datadog Access Token, potentially risking monitoring and analytics data exposure and manipulation." +regex = '''(?i)[\w.-]{0,50}?(?:datadog)(?:[ \t\w.-]{0,20})[\s'"]{0,3}(?:=|>|:{1,3}=|\|\||:|=>|\?=|,)[\x60'"\s=]{0,5}([a-z0-9]{40})(?:[\x60'"\s;]|\\[nr]|$)''' +keywords = ["datadog"] + +[[rules]] +id = "defined-networking-api-token" +description = "Identified a Defined Networking API token, which could lead to unauthorized network operations and data breaches." +regex = '''(?i)[\w.-]{0,50}?(?:dnkey)(?:[ \t\w.-]{0,20})[\s'"]{0,3}(?:=|>|:{1,3}=|\|\||:|=>|\?=|,)[\x60'"\s=]{0,5}(dnkey-[a-z0-9=_\-]{26}-[a-z0-9=_\-]{52})(?:[\x60'"\s;]|\\[nr]|$)''' +keywords = ["dnkey"] + +[[rules]] +id = "digitalocean-access-token" +description = "Found a DigitalOcean OAuth Access Token, risking unauthorized cloud resource access and data compromise." +regex = '''\b(doo_v1_[a-f0-9]{64})(?:[\x60'"\s;]|\\[nr]|$)''' +entropy = 3 +keywords = ["doo_v1_"] + +[[rules]] +id = "digitalocean-pat" +description = "Discovered a DigitalOcean Personal Access Token, posing a threat to cloud infrastructure security and data privacy." +regex = '''\b(dop_v1_[a-f0-9]{64})(?:[\x60'"\s;]|\\[nr]|$)''' +entropy = 3 +keywords = ["dop_v1_"] + +[[rules]] +id = "digitalocean-refresh-token" +description = "Uncovered a DigitalOcean OAuth Refresh Token, which could allow prolonged unauthorized access and resource manipulation." +regex = '''(?i)\b(dor_v1_[a-f0-9]{64})(?:[\x60'"\s;]|\\[nr]|$)''' +keywords = ["dor_v1_"] + +[[rules]] +id = "discord-api-token" +description = "Detected a Discord API key, potentially compromising communication channels and user data privacy on Discord." +regex = '''(?i)[\w.-]{0,50}?(?:discord)(?:[ \t\w.-]{0,20})[\s'"]{0,3}(?:=|>|:{1,3}=|\|\||:|=>|\?=|,)[\x60'"\s=]{0,5}([a-f0-9]{64})(?:[\x60'"\s;]|\\[nr]|$)''' +keywords = ["discord"] + +[[rules]] +id = "discord-client-id" +description = "Identified a Discord client ID, which may lead to unauthorized integrations and data exposure in Discord applications." +regex = '''(?i)[\w.-]{0,50}?(?:discord)(?:[ \t\w.-]{0,20})[\s'"]{0,3}(?:=|>|:{1,3}=|\|\||:|=>|\?=|,)[\x60'"\s=]{0,5}([0-9]{18})(?:[\x60'"\s;]|\\[nr]|$)''' +entropy = 2 +keywords = ["discord"] + +[[rules]] +id = "discord-client-secret" +description = "Discovered a potential Discord client secret, risking compromised Discord bot integrations and data leaks." +regex = '''(?i)[\w.-]{0,50}?(?:discord)(?:[ \t\w.-]{0,20})[\s'"]{0,3}(?:=|>|:{1,3}=|\|\||:|=>|\?=|,)[\x60'"\s=]{0,5}([a-z0-9=_\-]{32})(?:[\x60'"\s;]|\\[nr]|$)''' +entropy = 2 +keywords = ["discord"] + +[[rules]] +id = "doppler-api-token" +description = "Discovered a Doppler API token, posing a risk to environment and secrets management security." +regex = '''dp\.pt\.(?i)[a-z0-9]{43}''' +entropy = 2 +keywords = ["dp.pt."] + +[[rules]] +id = "droneci-access-token" +description = "Detected a Droneci Access Token, potentially compromising continuous integration and deployment workflows." +regex = '''(?i)[\w.-]{0,50}?(?:droneci)(?:[ \t\w.-]{0,20})[\s'"]{0,3}(?:=|>|:{1,3}=|\|\||:|=>|\?=|,)[\x60'"\s=]{0,5}([a-z0-9]{32})(?:[\x60'"\s;]|\\[nr]|$)''' +keywords = ["droneci"] + +[[rules]] +id = "dropbox-api-token" +description = "Identified a Dropbox API secret, which could lead to unauthorized file access and data breaches in Dropbox storage." +regex = '''(?i)[\w.-]{0,50}?(?:dropbox)(?:[ \t\w.-]{0,20})[\s'"]{0,3}(?:=|>|:{1,3}=|\|\||:|=>|\?=|,)[\x60'"\s=]{0,5}([a-z0-9]{15})(?:[\x60'"\s;]|\\[nr]|$)''' +keywords = ["dropbox"] + +[[rules]] +id = "dropbox-long-lived-api-token" +description = "Found a Dropbox long-lived API token, risking prolonged unauthorized access to cloud storage and sensitive data." +regex = '''(?i)[\w.-]{0,50}?(?:dropbox)(?:[ \t\w.-]{0,20})[\s'"]{0,3}(?:=|>|:{1,3}=|\|\||:|=>|\?=|,)[\x60'"\s=]{0,5}([a-z0-9]{11}(AAAAAAAAAA)[a-z0-9\-_=]{43})(?:[\x60'"\s;]|\\[nr]|$)''' +keywords = ["dropbox"] + +[[rules]] +id = "dropbox-short-lived-api-token" +description = "Discovered a Dropbox short-lived API token, posing a risk of temporary but potentially harmful data access and manipulation." +regex = '''(?i)[\w.-]{0,50}?(?:dropbox)(?:[ \t\w.-]{0,20})[\s'"]{0,3}(?:=|>|:{1,3}=|\|\||:|=>|\?=|,)[\x60'"\s=]{0,5}(sl\.[a-z0-9\-=_]{135})(?:[\x60'"\s;]|\\[nr]|$)''' +keywords = ["dropbox"] + +[[rules]] +id = "duffel-api-token" +description = "Uncovered a Duffel API token, which may compromise travel platform integrations and sensitive customer data." +regex = '''duffel_(?:test|live)_(?i)[a-z0-9_\-=]{43}''' +entropy = 2 +keywords = ["duffel_"] + +[[rules]] +id = "dynatrace-api-token" +description = "Detected a Dynatrace API token, potentially risking application performance monitoring and data exposure." +regex = '''dt0c01\.(?i)[a-z0-9]{24}\.[a-z0-9]{64}''' +entropy = 4 +keywords = ["dt0c01."] + +[[rules]] +id = "easypost-api-token" +description = "Identified an EasyPost API token, which could lead to unauthorized postal and shipment service access and data exposure." +regex = '''\bEZAK(?i)[a-z0-9]{54}\b''' +entropy = 2 +keywords = ["ezak"] + +[[rules]] +id = "easypost-test-api-token" +description = "Detected an EasyPost test API token, risking exposure of test environments and potentially sensitive shipment data." +regex = '''\bEZTK(?i)[a-z0-9]{54}\b''' +entropy = 2 +keywords = ["eztk"] + +[[rules]] +id = "etsy-access-token" +description = "Found an Etsy Access Token, potentially compromising Etsy shop management and customer data." +regex = '''(?i)[\w.-]{0,50}?(?:(?-i:ETSY|[Ee]tsy))(?:[ \t\w.-]{0,20})[\s'"]{0,3}(?:=|>|:{1,3}=|\|\||:|=>|\?=|,)[\x60'"\s=]{0,5}([a-z0-9]{24})(?:[\x60'"\s;]|\\[nr]|$)''' +entropy = 3 +keywords = ["etsy"] + +[[rules]] +id = "facebook-access-token" +description = "Discovered a Facebook Access Token, posing a risk of unauthorized access to Facebook accounts and personal data exposure." +regex = '''(?i)\b(\d{15,16}(\||%)[0-9a-z\-_]{27,40})(?:[\x60'"\s;]|\\[nr]|$)''' +entropy = 3 +keywords = ["facebook"] + +[[rules]] +id = "facebook-page-access-token" +description = "Discovered a Facebook Page Access Token, posing a risk of unauthorized access to Facebook accounts and personal data exposure." +regex = '''\b(EAA[MC](?i)[a-z0-9]{100,})(?:[\x60'"\s;]|\\[nr]|$)''' +entropy = 4 +keywords = [ + "eaam", + "eaac", +] + +[[rules]] +id = "facebook-secret" +description = "Discovered a Facebook Application secret, posing a risk of unauthorized access to Facebook accounts and personal data exposure." +regex = '''(?i)[\w.-]{0,50}?(?:facebook)(?:[ \t\w.-]{0,20})[\s'"]{0,3}(?:=|>|:{1,3}=|\|\||:|=>|\?=|,)[\x60'"\s=]{0,5}([a-f0-9]{32})(?:[\x60'"\s;]|\\[nr]|$)''' +entropy = 3 +keywords = ["facebook"] + +[[rules]] +id = "fastly-api-token" +description = "Uncovered a Fastly API key, which may compromise CDN and edge cloud services, leading to content delivery and security issues." +regex = '''(?i)[\w.-]{0,50}?(?:fastly)(?:[ \t\w.-]{0,20})[\s'"]{0,3}(?:=|>|:{1,3}=|\|\||:|=>|\?=|,)[\x60'"\s=]{0,5}([a-z0-9=_\-]{32})(?:[\x60'"\s;]|\\[nr]|$)''' +keywords = ["fastly"] + +[[rules]] +id = "finicity-api-token" +description = "Detected a Finicity API token, potentially risking financial data access and unauthorized financial operations." +regex = '''(?i)[\w.-]{0,50}?(?:finicity)(?:[ \t\w.-]{0,20})[\s'"]{0,3}(?:=|>|:{1,3}=|\|\||:|=>|\?=|,)[\x60'"\s=]{0,5}([a-f0-9]{32})(?:[\x60'"\s;]|\\[nr]|$)''' +keywords = ["finicity"] + +[[rules]] +id = "finicity-client-secret" +description = "Identified a Finicity Client Secret, which could lead to compromised financial service integrations and data breaches." +regex = '''(?i)[\w.-]{0,50}?(?:finicity)(?:[ \t\w.-]{0,20})[\s'"]{0,3}(?:=|>|:{1,3}=|\|\||:|=>|\?=|,)[\x60'"\s=]{0,5}([a-z0-9]{20})(?:[\x60'"\s;]|\\[nr]|$)''' +keywords = ["finicity"] + +[[rules]] +id = "finnhub-access-token" +description = "Found a Finnhub Access Token, risking unauthorized access to financial market data and analytics." +regex = '''(?i)[\w.-]{0,50}?(?:finnhub)(?:[ \t\w.-]{0,20})[\s'"]{0,3}(?:=|>|:{1,3}=|\|\||:|=>|\?=|,)[\x60'"\s=]{0,5}([a-z0-9]{20})(?:[\x60'"\s;]|\\[nr]|$)''' +keywords = ["finnhub"] + +[[rules]] +id = "flickr-access-token" +description = "Discovered a Flickr Access Token, posing a risk of unauthorized photo management and potential data leakage." +regex = '''(?i)[\w.-]{0,50}?(?:flickr)(?:[ \t\w.-]{0,20})[\s'"]{0,3}(?:=|>|:{1,3}=|\|\||:|=>|\?=|,)[\x60'"\s=]{0,5}([a-z0-9]{32})(?:[\x60'"\s;]|\\[nr]|$)''' +keywords = ["flickr"] + +[[rules]] +id = "flutterwave-encryption-key" +description = "Uncovered a Flutterwave Encryption Key, which may compromise payment processing and sensitive financial information." +regex = '''FLWSECK_TEST-(?i)[a-h0-9]{12}''' +entropy = 2 +keywords = ["flwseck_test"] + +[[rules]] +id = "flutterwave-public-key" +description = "Detected a Finicity Public Key, potentially exposing public cryptographic operations and integrations." +regex = '''FLWPUBK_TEST-(?i)[a-h0-9]{32}-X''' +entropy = 2 +keywords = ["flwpubk_test"] + +[[rules]] +id = "flutterwave-secret-key" +description = "Identified a Flutterwave Secret Key, risking unauthorized financial transactions and data breaches." +regex = '''FLWSECK_TEST-(?i)[a-h0-9]{32}-X''' +entropy = 2 +keywords = ["flwseck_test"] + +[[rules]] +id = "flyio-access-token" +description = "Uncovered a Fly.io API key" +regex = '''\b((?:fo1_[\w-]{43}|fm1[ar]_[a-zA-Z0-9+\/]{100,}={0,3}|fm2_[a-zA-Z0-9+\/]{100,}={0,3}))(?:[\x60'"\s;]|\\[nr]|$)''' +entropy = 4 +keywords = [ + "fo1_", + "fm1", + "fm2_", +] + +[[rules]] +id = "frameio-api-token" +description = "Found a Frame.io API token, potentially compromising video collaboration and project management." +regex = '''fio-u-(?i)[a-z0-9\-_=]{64}''' +keywords = ["fio-u-"] + +[[rules]] +id = "freemius-secret-key" +description = "Detected a Freemius secret key, potentially exposing sensitive information." +regex = '''(?i)["']secret_key["']\s*=>\s*["'](sk_[\S]{29})["']''' +path = '''(?i)\.php$''' +keywords = ["secret_key"] + +[[rules]] +id = "freshbooks-access-token" +description = "Discovered a Freshbooks Access Token, posing a risk to accounting software access and sensitive financial data exposure." +regex = '''(?i)[\w.-]{0,50}?(?:freshbooks)(?:[ \t\w.-]{0,20})[\s'"]{0,3}(?:=|>|:{1,3}=|\|\||:|=>|\?=|,)[\x60'"\s=]{0,5}([a-z0-9]{64})(?:[\x60'"\s;]|\\[nr]|$)''' +keywords = ["freshbooks"] + +[[rules]] +id = "gcp-api-key" +description = "Uncovered a GCP API key, which could lead to unauthorized access to Google Cloud services and data breaches." +regex = '''\b(AIza[\w-]{35})(?:[\x60'"\s;]|\\[nr]|$)''' +entropy = 3 +keywords = ["aiza"] +[[rules.allowlists]] +regexes = [ + '''AIzaSyabcdefghijklmnopqrstuvwxyz1234567''', + '''AIzaSyAnLA7NfeLquW1tJFpx_eQCxoX-oo6YyIs''', + '''AIzaSyCkEhVjf3pduRDt6d1yKOMitrUEke8agEM''', + '''AIzaSyDMAScliyLx7F0NPDEJi1QmyCgHIAODrlU''', + '''AIzaSyD3asb-2pEZVqMkmL6M9N6nHZRR_znhrh0''', + '''AIzayDNSXIbFmlXbIE6mCzDLQAqITYefhixbX4A''', + '''AIzaSyAdOS2zB6NCsk1pCdZ4-P6GBdi_UUPwX7c''', + '''AIzaSyASWm6HmTMdYWpgMnjRBjxcQ9CKctWmLd4''', + '''AIzaSyANUvH9H9BsUccjsu2pCmEkOPjjaXeDQgY''', + '''AIzaSyA5_iVawFQ8ABuTZNUdcwERLJv_a_p4wtM''', + '''AIzaSyA4UrcGxgwQFTfaI3no3t7Lt1sjmdnP5sQ''', + '''AIzaSyDSb51JiIcB6OJpwwMicseKRhhrOq1cS7g''', + '''AIzaSyBF2RrAIm4a0mO64EShQfqfd2AFnzAvvuU''', + '''AIzaSyBcE-OOIbhjyR83gm4r2MFCu4MJmprNXsw''', + '''AIzaSyB8qGxt4ec15vitgn44duC5ucxaOi4FmqE''', + '''AIzaSyA8vmApnrHNFE0bApF4hoZ11srVL_n0nvY''', +] + +[[rules]] +id = "generic-api-key" +description = "Detected a Generic API Key, potentially exposing access to various services and sensitive operations." +regex = '''(?i)[\w.-]{0,50}?(?:access|auth|(?-i:[Aa]pi|API)|credential|creds|key|passw(?:or)?d|secret|token)(?:[ \t\w.-]{0,20})[\s'"]{0,3}(?:=|>|:{1,3}=|\|\||:|=>|\?=|,)[\x60'"\s=]{0,5}([\w.=-]{10,150}|[a-z0-9][a-z0-9+/]{11,}={0,3})(?:[\x60'"\s;]|\\[nr]|$)''' +entropy = 3.5 +keywords = [ + "access", + "api", + "auth", + "key", + "credential", + "creds", + "passwd", + "password", + "secret", + "token", +] +[[rules.allowlists]] +regexes = [ + '''^[a-zA-Z_.-]+$''', +] +[[rules.allowlists]] +regexTarget = "match" +regexes = [ + '''(?i)(?:access(?:ibility|or)|access[_.-]?id|random[_.-]?access|api[_.-]?(?:id|name|version)|rapid|capital|[a-z0-9-]*?api[a-z0-9-]*?:jar:|author|X-MS-Exchange-Organization-Auth|Authentication-Results|(?:credentials?[_.-]?id|withCredentials)|(?:bucket|foreign|hot|idx|natural|primary|pub(?:lic)?|schema|sequence)[_.-]?key|(?:turkey)|key[_.-]?(?:alias|board|code|frame|id|length|mesh|name|pair|press(?:ed)?|ring|selector|signature|size|stone|storetype|word|up|down|left|right)|key[_.-]?vault[_.-]?(?:id|name)|keyVaultToStoreSecrets|key(?:store|tab)[_.-]?(?:file|path)|issuerkeyhash|(?-i:[DdMm]onkey|[DM]ONKEY)|keying|(?:secret)[_.-]?(?:length|name|size)|UserSecretsId|(?:csrf)[_.-]?token|(?:io\.jsonwebtoken[ \t]?:[ \t]?[\w-]+)|(?:api|credentials|token)[_.-]?(?:endpoint|ur[il])|public[_.-]?token|(?:key|token)[_.-]?file|(?-i:(?:[A-Z_]+=\n[A-Z_]+=|[a-z_]+=\n[a-z_]+=)(?:\n|\z))|(?-i:(?:[A-Z.]+=\n[A-Z.]+=|[a-z.]+=\n[a-z.]+=)(?:\n|\z)))''', +] +stopwords = [ + "000000", + "aaaaaa", + "about", + "abstract", + "academy", + "acces", + "account", + "act-", + "act.", + "act_", + "action", + "active", + "actively", + "activity", + "adapter", + "add-", + "add.", + "add_", + "add-on", + "addon", + "addres", + "admin", + "adobe", + "advanced", + "adventure", + "agent", + "agile", + "air-", + "air.", + "air_", + "ajax", + "akka", + "alert", + "alfred", + "algorithm", + "all-", + "all.", + "all_", + "alloy", + "alpha", + "amazon", + "amqp", + "analysi", + "analytic", + "analyzer", + "android", + "angular", + "angularj", + "animate", + "animation", + "another", + "ansible", + "answer", + "ant-", + "ant.", + "ant_", + "any-", + "any.", + "any_", + "apache", + "app-", + "app-", + "app.", + "app.", + "app_", + "app_", + "apple", + "arch", + "archive", + "archived", + "arduino", + "array", + "art-", + "art.", + "art_", + "article", + "asp-", + "asp.", + "asp_", + "asset", + "async", + "atom", + "attention", + "audio", + "audit", + "aura", + "auth", + "author", + "author", + "authorize", + "auto", + "automated", + "automatic", + "awesome", + "aws_", + "azure", + "back", + "backbone", + "backend", + "backup", + "bar-", + "bar.", + "bar_", + "base", + "based", + "bash", + "basic", + "batch", + "been", + "beer", + "behavior", + "being", + "benchmark", + "best", + "beta", + "better", + "big-", + "big.", + "big_", + "binary", + "binding", + "bit-", + "bit.", + "bit_", + "bitcoin", + "block", + "blog", + "board", + "book", + "bookmark", + "boost", + "boot", + "bootstrap", + "bosh", + "bot-", + "bot.", + "bot_", + "bower", + "box-", + "box.", + "box_", + "boxen", + "bracket", + "branch", + "bridge", + "browser", + "brunch", + "buffer", + "bug-", + "bug.", + "bug_", + "build", + "builder", + "building", + "buildout", + "buildpack", + "built", + "bundle", + "busines", + "but-", + "but.", + "but_", + "button", + "cache", + "caching", + "cakephp", + "calendar", + "call", + "camera", + "campfire", + "can-", + "can.", + "can_", + "canva", + "captcha", + "capture", + "card", + "carousel", + "case", + "cassandra", + "cat-", + "cat.", + "cat_", + "category", + "center", + "cento", + "challenge", + "change", + "changelog", + "channel", + "chart", + "chat", + "cheat", + "check", + "checker", + "chef", + "ches", + "chinese", + "chosen", + "chrome", + "ckeditor", + "clas", + "classe", + "classic", + "clean", + "cli-", + "cli.", + "cli_", + "client", + "client", + "clojure", + "clone", + "closure", + "cloud", + "club", + "cluster", + "cms-", + "cms_", + "coco", + "code", + "coding", + "coffee", + "color", + "combination", + "combo", + "command", + "commander", + "comment", + "commit", + "common", + "community", + "compas", + "compiler", + "complete", + "component", + "composer", + "computer", + "computing", + "con-", + "con.", + "con_", + "concept", + "conf", + "config", + "config", + "connect", + "connector", + "console", + "contact", + "container", + "contao", + "content", + "contest", + "context", + "control", + "convert", + "converter", + "conway'", + "cookbook", + "cookie", + "cool", + "copy", + "cordova", + "core", + "couchbase", + "couchdb", + "countdown", + "counter", + "course", + "craft", + "crawler", + "create", + "creating", + "creator", + "credential", + "crm-", + "crm.", + "crm_", + "cros", + "crud", + "csv-", + "csv.", + "csv_", + "cube", + "cucumber", + "cuda", + "current", + "currently", + "custom", + "daemon", + "dark", + "dart", + "dash", + "dashboard", + "data", + "database", + "date", + "day-", + "day.", + "day_", + "dead", + "debian", + "debug", + "debug", + "debugger", + "deck", + "define", + "del-", + "del.", + "del_", + "delete", + "demo", + "deploy", + "design", + "designer", + "desktop", + "detection", + "detector", + "dev-", + "dev.", + "dev_", + "develop", + "developer", + "device", + "devise", + "diff", + "digital", + "directive", + "directory", + "discovery", + "display", + "django", + "dns-", + "dns_", + "doc-", + "doc-", + "doc.", + "doc.", + "doc_", + "doc_", + "docker", + "docpad", + "doctrine", + "document", + "doe-", + "doe.", + "doe_", + "dojo", + "dom-", + "dom.", + "dom_", + "domain", + "done", + "don't", + "dot-", + "dot.", + "dot_", + "dotfile", + "download", + "draft", + "drag", + "drill", + "drive", + "driven", + "driver", + "drop", + "dropbox", + "drupal", + "dsl-", + "dsl.", + "dsl_", + "dynamic", + "easy", + "_ec2_", + "ecdsa", + "eclipse", + "edit", + "editing", + "edition", + "editor", + "element", + "emac", + "email", + "embed", + "embedded", + "ember", + "emitter", + "emulator", + "encoding", + "endpoint", + "engine", + "english", + "enhanced", + "entity", + "entry", + "env_", + "episode", + "erlang", + "error", + "espresso", + "event", + "evented", + "example", + "example", + "exchange", + "exercise", + "experiment", + "expire", + "exploit", + "explorer", + "export", + "exporter", + "expres", + "ext-", + "ext.", + "ext_", + "extended", + "extension", + "external", + "extra", + "extractor", + "fabric", + "facebook", + "factory", + "fake", + "fast", + "feature", + "feed", + "fewfwef", + "ffmpeg", + "field", + "file", + "filter", + "find", + "finder", + "firefox", + "firmware", + "first", + "fish", + "fix-", + "fix_", + "flash", + "flask", + "flat", + "flex", + "flexible", + "flickr", + "flow", + "fluent", + "fluentd", + "fluid", + "folder", + "font", + "force", + "foreman", + "fork", + "form", + "format", + "formatter", + "forum", + "foundry", + "framework", + "free", + "friend", + "friendly", + "front-end", + "frontend", + "ftp-", + "ftp.", + "ftp_", + "fuel", + "full", + "fun-", + "fun.", + "fun_", + "func", + "future", + "gaia", + "gallery", + "game", + "gateway", + "gem-", + "gem.", + "gem_", + "gen-", + "gen.", + "gen_", + "general", + "generator", + "generic", + "genetic", + "get-", + "get.", + "get_", + "getenv", + "getting", + "ghost", + "gist", + "git-", + "git.", + "git_", + "github", + "gitignore", + "gitlab", + "glas", + "gmail", + "gnome", + "gnu-", + "gnu.", + "gnu_", + "goal", + "golang", + "gollum", + "good", + "google", + "gpu-", + "gpu.", + "gpu_", + "gradle", + "grail", + "graph", + "graphic", + "great", + "grid", + "groovy", + "group", + "grunt", + "guard", + "gui-", + "gui.", + "gui_", + "guide", + "guideline", + "gulp", + "gwt-", + "gwt.", + "gwt_", + "hack", + "hackathon", + "hacker", + "hacking", + "hadoop", + "haml", + "handler", + "hardware", + "has-", + "has_", + "hash", + "haskell", + "have", + "haxe", + "hello", + "help", + "helper", + "here", + "hero", + "heroku", + "high", + "hipchat", + "history", + "home", + "homebrew", + "homepage", + "hook", + "host", + "hosting", + "hot-", + "hot.", + "hot_", + "house", + "how-", + "how.", + "how_", + "html", + "http", + "hub-", + "hub.", + "hub_", + "hubot", + "human", + "icon", + "ide-", + "ide.", + "ide_", + "idea", + "identity", + "idiomatic", + "image", + "impact", + "import", + "important", + "importer", + "impres", + "index", + "infinite", + "info", + "injection", + "inline", + "input", + "inside", + "inspector", + "instagram", + "install", + "installer", + "instant", + "intellij", + "interface", + "internet", + "interview", + "into", + "intro", + "ionic", + "iphone", + "ipython", + "irc-", + "irc_", + "iso-", + "iso.", + "iso_", + "issue", + "jade", + "jasmine", + "java", + "jbos", + "jekyll", + "jenkin", + "jetbrains", + "job-", + "job.", + "job_", + "joomla", + "jpa-", + "jpa.", + "jpa_", + "jquery", + "json", + "just", + "kafka", + "karma", + "kata", + "kernel", + "keyboard", + "kindle", + "kit-", + "kit.", + "kit_", + "kitchen", + "knife", + "koan", + "kohana", + "lab-", + "lab-", + "lab.", + "lab.", + "lab_", + "lab_", + "lambda", + "lamp", + "language", + "laravel", + "last", + "latest", + "latex", + "launcher", + "layer", + "layout", + "lazy", + "ldap", + "leaflet", + "league", + "learn", + "learning", + "led-", + "led.", + "led_", + "leetcode", + "les-", + "les.", + "les_", + "level", + "leveldb", + "lib-", + "lib.", + "lib_", + "librarie", + "library", + "license", + "life", + "liferay", + "light", + "lightbox", + "like", + "line", + "link", + "linked", + "linkedin", + "linux", + "lisp", + "list", + "lite", + "little", + "load", + "loader", + "local", + "location", + "lock", + "log-", + "log.", + "log_", + "logger", + "logging", + "logic", + "login", + "logstash", + "longer", + "look", + "love", + "lua-", + "lua.", + "lua_", + "mac-", + "mac.", + "mac_", + "machine", + "made", + "magento", + "magic", + "mail", + "make", + "maker", + "making", + "man-", + "man.", + "man_", + "manage", + "manager", + "manifest", + "manual", + "map-", + "map-", + "map.", + "map.", + "map_", + "map_", + "mapper", + "mapping", + "markdown", + "markup", + "master", + "math", + "matrix", + "maven", + "md5", + "mean", + "media", + "mediawiki", + "meetup", + "memcached", + "memory", + "menu", + "merchant", + "message", + "messaging", + "meta", + "metadata", + "meteor", + "method", + "metric", + "micro", + "middleman", + "migration", + "minecraft", + "miner", + "mini", + "minimal", + "mirror", + "mit-", + "mit.", + "mit_", + "mobile", + "mocha", + "mock", + "mod-", + "mod.", + "mod_", + "mode", + "model", + "modern", + "modular", + "module", + "modx", + "money", + "mongo", + "mongodb", + "mongoid", + "mongoose", + "monitor", + "monkey", + "more", + "motion", + "moved", + "movie", + "mozilla", + "mqtt", + "mule", + "multi", + "multiple", + "music", + "mustache", + "mvc-", + "mvc.", + "mvc_", + "mysql", + "nagio", + "name", + "native", + "need", + "neo-", + "neo.", + "neo_", + "nest", + "nested", + "net-", + "net.", + "net_", + "nette", + "network", + "new-", + "new-", + "new.", + "new.", + "new_", + "new_", + "next", + "nginx", + "ninja", + "nlp-", + "nlp.", + "nlp_", + "node", + "nodej", + "nosql", + "not-", + "not.", + "not_", + "note", + "notebook", + "notepad", + "notice", + "notifier", + "now-", + "now.", + "now_", + "number", + "oauth", + "object", + "objective", + "obsolete", + "ocaml", + "octopres", + "official", + "old-", + "old.", + "old_", + "onboard", + "online", + "only", + "open", + "opencv", + "opengl", + "openshift", + "openwrt", + "option", + "oracle", + "org-", + "org.", + "org_", + "origin", + "original", + "orm-", + "orm.", + "orm_", + "osx-", + "osx_", + "our-", + "our.", + "our_", + "out-", + "out.", + "out_", + "output", + "over", + "overview", + "own-", + "own.", + "own_", + "pack", + "package", + "packet", + "page", + "page", + "panel", + "paper", + "paperclip", + "para", + "parallax", + "parallel", + "parse", + "parser", + "parsing", + "particle", + "party", + "password", + "patch", + "path", + "pattern", + "payment", + "paypal", + "pdf-", + "pdf.", + "pdf_", + "pebble", + "people", + "perl", + "personal", + "phalcon", + "phoenix", + "phone", + "phonegap", + "photo", + "php-", + "php.", + "php_", + "physic", + "picker", + "pipeline", + "platform", + "play", + "player", + "please", + "plu-", + "plu.", + "plu_", + "plug-in", + "plugin", + "plupload", + "png-", + "png.", + "png_", + "poker", + "polyfill", + "polymer", + "pool", + "pop-", + "pop.", + "pop_", + "popcorn", + "popup", + "port", + "portable", + "portal", + "portfolio", + "post", + "power", + "powered", + "powerful", + "prelude", + "pretty", + "preview", + "principle", + "print", + "pro-", + "pro.", + "pro_", + "problem", + "proc", + "product", + "profile", + "profiler", + "program", + "progres", + "project", + "protocol", + "prototype", + "provider", + "proxy", + "public", + "pull", + "puppet", + "pure", + "purpose", + "push", + "pusher", + "pyramid", + "python", + "quality", + "query", + "queue", + "quick", + "rabbitmq", + "rack", + "radio", + "rail", + "railscast", + "random", + "range", + "raspberry", + "rdf-", + "rdf.", + "rdf_", + "react", + "reactive", + "read", + "reader", + "readme", + "ready", + "real", + "reality", + "real-time", + "realtime", + "recipe", + "recorder", + "red-", + "red.", + "red_", + "reddit", + "redi", + "redmine", + "reference", + "refinery", + "refresh", + "registry", + "related", + "release", + "remote", + "rendering", + "repo", + "report", + "request", + "require", + "required", + "requirej", + "research", + "resource", + "response", + "resque", + "rest", + "restful", + "resume", + "reveal", + "reverse", + "review", + "riak", + "rich", + "right", + "ring", + "robot", + "role", + "room", + "router", + "routing", + "rpc-", + "rpc.", + "rpc_", + "rpg-", + "rpg.", + "rpg_", + "rspec", + "ruby-", + "ruby.", + "ruby_", + "rule", + "run-", + "run.", + "run_", + "runner", + "running", + "runtime", + "rust", + "rvm-", + "rvm.", + "rvm_", + "salt", + "sample", + "sample", + "sandbox", + "sas-", + "sas.", + "sas_", + "sbt-", + "sbt.", + "sbt_", + "scala", + "scalable", + "scanner", + "schema", + "scheme", + "school", + "science", + "scraper", + "scratch", + "screen", + "script", + "scroll", + "scs-", + "scs.", + "scs_", + "sdk-", + "sdk.", + "sdk_", + "sdl-", + "sdl.", + "sdl_", + "search", + "secure", + "security", + "see-", + "see.", + "see_", + "seed", + "select", + "selector", + "selenium", + "semantic", + "sencha", + "send", + "sentiment", + "serie", + "server", + "service", + "session", + "set-", + "set.", + "set_", + "setting", + "setting", + "setup", + "sha1", + "sha2", + "sha256", + "share", + "shared", + "sharing", + "sheet", + "shell", + "shield", + "shipping", + "shop", + "shopify", + "shortener", + "should", + "show", + "showcase", + "side", + "silex", + "simple", + "simulator", + "single", + "site", + "skeleton", + "sketch", + "skin", + "slack", + "slide", + "slider", + "slim", + "small", + "smart", + "smtp", + "snake", + "snapshot", + "snippet", + "soap", + "social", + "socket", + "software", + "solarized", + "solr", + "solution", + "solver", + "some", + "soon", + "source", + "space", + "spark", + "spatial", + "spec", + "sphinx", + "spine", + "spotify", + "spree", + "spring", + "sprite", + "sql-", + "sql.", + "sql_", + "sqlite", + "ssh-", + "ssh.", + "ssh_", + "stack", + "staging", + "standard", + "stanford", + "start", + "started", + "starter", + "startup", + "stat", + "statamic", + "state", + "static", + "statistic", + "statsd", + "statu", + "steam", + "step", + "still", + "stm-", + "stm.", + "stm_", + "storage", + "store", + "storm", + "story", + "strategy", + "stream", + "streaming", + "string", + "stripe", + "structure", + "studio", + "study", + "stuff", + "style", + "sublime", + "sugar", + "suite", + "summary", + "super", + "support", + "supported", + "svg-", + "svg.", + "svg_", + "svn-", + "svn.", + "svn_", + "swagger", + "swift", + "switch", + "switcher", + "symfony", + "symphony", + "sync", + "synopsi", + "syntax", + "system", + "system", + "tab-", + "tab-", + "tab.", + "tab.", + "tab_", + "tab_", + "table", + "tag-", + "tag-", + "tag.", + "tag.", + "tag_", + "tag_", + "talk", + "target", + "task", + "tcp-", + "tcp.", + "tcp_", + "tdd-", + "tdd.", + "tdd_", + "team", + "tech", + "template", + "term", + "terminal", + "testing", + "tetri", + "text", + "textmate", + "theme", + "theory", + "three", + "thrift", + "time", + "timeline", + "timer", + "tiny", + "tinymce", + "tip-", + "tip.", + "tip_", + "title", + "todo", + "todomvc", + "token", + "tool", + "toolbox", + "toolkit", + "top-", + "top.", + "top_", + "tornado", + "touch", + "tower", + "tracker", + "tracking", + "traffic", + "training", + "transfer", + "translate", + "transport", + "tree", + "trello", + "try-", + "try.", + "try_", + "tumblr", + "tut-", + "tut.", + "tut_", + "tutorial", + "tweet", + "twig", + "twitter", + "type", + "typo", + "ubuntu", + "uiview", + "ultimate", + "under", + "unit", + "unity", + "universal", + "unix", + "update", + "updated", + "upgrade", + "upload", + "uploader", + "uri-", + "uri.", + "uri_", + "url-", + "url.", + "url_", + "usage", + "usb-", + "usb.", + "usb_", + "use-", + "use.", + "use_", + "used", + "useful", + "user", + "using", + "util", + "utilitie", + "utility", + "vagrant", + "validator", + "value", + "variou", + "varnish", + "version", + "via-", + "via.", + "via_", + "video", + "view", + "viewer", + "vim-", + "vim.", + "vim_", + "vimrc", + "virtual", + "vision", + "visual", + "vpn", + "want", + "warning", + "watch", + "watcher", + "wave", + "way-", + "way.", + "way_", + "weather", + "web-", + "web_", + "webapp", + "webgl", + "webhook", + "webkit", + "webrtc", + "website", + "websocket", + "welcome", + "welcome", + "what", + "what'", + "when", + "where", + "which", + "why-", + "why.", + "why_", + "widget", + "wifi", + "wiki", + "win-", + "win.", + "win_", + "window", + "wip-", + "wip.", + "wip_", + "within", + "without", + "wizard", + "word", + "wordpres", + "work", + "worker", + "workflow", + "working", + "workshop", + "world", + "wrapper", + "write", + "writer", + "writing", + "written", + "www-", + "www.", + "www_", + "xamarin", + "xcode", + "xml-", + "xml.", + "xml_", + "xmpp", + "xxxxxx", + "yahoo", + "yaml", + "yandex", + "yeoman", + "yet-", + "yet.", + "yet_", + "yii-", + "yii.", + "yii_", + "youtube", + "yui-", + "yui.", + "yui_", + "zend", + "zero", + "zip-", + "zip.", + "zip_", + "zsh-", + "zsh.", + "zsh_", + "6fe4476ee5a1832882e326b506d14126", +] +[[rules.allowlists]] +regexTarget = "line" +regexes = [ + '''--mount=type=secret,''', + '''import[ \t]+{[ \t\w,]+}[ \t]+from[ \t]+['"][^'"]+['"]''', +] +[[rules.allowlists]] +condition = "AND" +paths = [ + '''\.bb$''','''\.bbappend$''','''\.bbclass$''','''\.inc$''', +] +regexTarget = "line" +regexes = [ + '''LICENSE[^=]*=\s*"[^"]+''', + '''LIC_FILES_CHKSUM[^=]*=\s*"[^"]+''', + '''SRC[^=]*=\s*"[a-zA-Z0-9]+''', +] + +[[rules]] +id = "github-app-token" +description = "Identified a GitHub App Token, which may compromise GitHub application integrations and source code security." +regex = '''(?:ghu|ghs)_[0-9a-zA-Z]{36}''' +entropy = 3 +keywords = [ + "ghu_", + "ghs_", +] +[[rules.allowlists]] +paths = [ + '''(?:^|/)@octokit/auth-token/README\.md$''', +] + +[[rules]] +id = "github-fine-grained-pat" +description = "Found a GitHub Fine-Grained Personal Access Token, risking unauthorized repository access and code manipulation." +regex = '''github_pat_\w{82}''' +entropy = 3 +keywords = ["github_pat_"] + +[[rules]] +id = "github-oauth" +description = "Discovered a GitHub OAuth Access Token, posing a risk of compromised GitHub account integrations and data leaks." +regex = '''gho_[0-9a-zA-Z]{36}''' +entropy = 3 +keywords = ["gho_"] + +[[rules]] +id = "github-pat" +description = "Uncovered a GitHub Personal Access Token, potentially leading to unauthorized repository access and sensitive content exposure." +regex = '''ghp_[0-9a-zA-Z]{36}''' +entropy = 3 +keywords = ["ghp_"] +[[rules.allowlists]] +paths = [ + '''(?:^|/)@octokit/auth-token/README\.md$''', +] + +[[rules]] +id = "github-refresh-token" +description = "Detected a GitHub Refresh Token, which could allow prolonged unauthorized access to GitHub services." +regex = '''ghr_[0-9a-zA-Z]{36}''' +entropy = 3 +keywords = ["ghr_"] + +[[rules]] +id = "gitlab-cicd-job-token" +description = "Identified a GitLab CI/CD Job Token, potential access to projects and some APIs on behalf of a user while the CI job is running." +regex = '''glcbt-[0-9a-zA-Z]{1,5}_[0-9a-zA-Z_-]{20}''' +entropy = 3 +keywords = ["glcbt-"] + +[[rules]] +id = "gitlab-deploy-token" +description = "Identified a GitLab Deploy Token, risking access to repositories, packages and containers with write access." +regex = '''gldt-[0-9a-zA-Z_\-]{20}''' +entropy = 3 +keywords = ["gldt-"] + +[[rules]] +id = "gitlab-feature-flag-client-token" +description = "Identified a GitLab feature flag client token, risks exposing user lists and features flags used by an application." +regex = '''glffct-[0-9a-zA-Z_\-]{20}''' +entropy = 3 +keywords = ["glffct-"] + +[[rules]] +id = "gitlab-feed-token" +description = "Identified a GitLab feed token, risking exposure of user data." +regex = '''glft-[0-9a-zA-Z_\-]{20}''' +entropy = 3 +keywords = ["glft-"] + +[[rules]] +id = "gitlab-incoming-mail-token" +description = "Identified a GitLab incoming mail token, risking manipulation of data sent by mail." +regex = '''glimt-[0-9a-zA-Z_\-]{25}''' +entropy = 3 +keywords = ["glimt-"] + +[[rules]] +id = "gitlab-kubernetes-agent-token" +description = "Identified a GitLab Kubernetes Agent token, risking access to repos and registry of projects connected via agent." +regex = '''glagent-[0-9a-zA-Z_\-]{50}''' +entropy = 3 +keywords = ["glagent-"] + +[[rules]] +id = "gitlab-oauth-app-secret" +description = "Identified a GitLab OIDC Application Secret, risking access to apps using GitLab as authentication provider." +regex = '''gloas-[0-9a-zA-Z_\-]{64}''' +entropy = 3 +keywords = ["gloas-"] + +[[rules]] +id = "gitlab-pat" +description = "Identified a GitLab Personal Access Token, risking unauthorized access to GitLab repositories and codebase exposure." +regex = '''glpat-[\w-]{20}''' +entropy = 3 +keywords = ["glpat-"] + +[[rules]] +id = "gitlab-pat-routable" +description = "Identified a GitLab Personal Access Token (routable), risking unauthorized access to GitLab repositories and codebase exposure." +regex = '''\bglpat-[0-9a-zA-Z_-]{27,300}\.[0-9a-z]{2}[0-9a-z]{7}\b''' +entropy = 4 +keywords = ["glpat-"] + +[[rules]] +id = "gitlab-ptt" +description = "Found a GitLab Pipeline Trigger Token, potentially compromising continuous integration workflows and project security." +regex = '''glptt-[0-9a-f]{40}''' +entropy = 3 +keywords = ["glptt-"] + +[[rules]] +id = "gitlab-rrt" +description = "Discovered a GitLab Runner Registration Token, posing a risk to CI/CD pipeline integrity and unauthorized access." +regex = '''GR1348941[\w-]{20}''' +entropy = 3 +keywords = ["gr1348941"] + +[[rules]] +id = "gitlab-runner-authentication-token" +description = "Discovered a GitLab Runner Authentication Token, posing a risk to CI/CD pipeline integrity and unauthorized access." +regex = '''glrt-[0-9a-zA-Z_\-]{20}''' +entropy = 3 +keywords = ["glrt-"] + +[[rules]] +id = "gitlab-runner-authentication-token-routable" +description = "Discovered a GitLab Runner Authentication Token (Routable), posing a risk to CI/CD pipeline integrity and unauthorized access." +regex = '''\bglrt-t\d_[0-9a-zA-Z_\-]{27,300}\.[0-9a-z]{2}[0-9a-z]{7}\b''' +entropy = 4 +keywords = ["glrt-"] + +[[rules]] +id = "gitlab-scim-token" +description = "Discovered a GitLab SCIM Token, posing a risk to unauthorized access for a organization or instance." +regex = '''glsoat-[0-9a-zA-Z_\-]{20}''' +entropy = 3 +keywords = ["glsoat-"] + +[[rules]] +id = "gitlab-session-cookie" +description = "Discovered a GitLab Session Cookie, posing a risk to unauthorized access to a user account." +regex = '''_gitlab_session=[0-9a-z]{32}''' +entropy = 3 +keywords = ["_gitlab_session="] + +[[rules]] +id = "gitter-access-token" +description = "Uncovered a Gitter Access Token, which may lead to unauthorized access to chat and communication services." +regex = '''(?i)[\w.-]{0,50}?(?:gitter)(?:[ \t\w.-]{0,20})[\s'"]{0,3}(?:=|>|:{1,3}=|\|\||:|=>|\?=|,)[\x60'"\s=]{0,5}([a-z0-9_-]{40})(?:[\x60'"\s;]|\\[nr]|$)''' +keywords = ["gitter"] + +[[rules]] +id = "gocardless-api-token" +description = "Detected a GoCardless API token, potentially risking unauthorized direct debit payment operations and financial data exposure." +regex = '''(?i)[\w.-]{0,50}?(?:gocardless)(?:[ \t\w.-]{0,20})[\s'"]{0,3}(?:=|>|:{1,3}=|\|\||:|=>|\?=|,)[\x60'"\s=]{0,5}(live_(?i)[a-z0-9\-_=]{40})(?:[\x60'"\s;]|\\[nr]|$)''' +keywords = [ + "live_", + "gocardless", +] + +[[rules]] +id = "grafana-api-key" +description = "Identified a Grafana API key, which could compromise monitoring dashboards and sensitive data analytics." +regex = '''(?i)\b(eyJrIjoi[A-Za-z0-9]{70,400}={0,3})(?:[\x60'"\s;]|\\[nr]|$)''' +entropy = 3 +keywords = ["eyjrijoi"] + +[[rules]] +id = "grafana-cloud-api-token" +description = "Found a Grafana cloud API token, risking unauthorized access to cloud-based monitoring services and data exposure." +regex = '''(?i)\b(glc_[A-Za-z0-9+/]{32,400}={0,3})(?:[\x60'"\s;]|\\[nr]|$)''' +entropy = 3 +keywords = ["glc_"] + +[[rules]] +id = "grafana-service-account-token" +description = "Discovered a Grafana service account token, posing a risk of compromised monitoring services and data integrity." +regex = '''(?i)\b(glsa_[A-Za-z0-9]{32}_[A-Fa-f0-9]{8})(?:[\x60'"\s;]|\\[nr]|$)''' +entropy = 3 +keywords = ["glsa_"] + +[[rules]] +id = "harness-api-key" +description = "Identified a Harness Access Token (PAT or SAT), risking unauthorized access to a Harness account." +regex = '''(?:pat|sat)\.[a-zA-Z0-9_-]{22}\.[a-zA-Z0-9]{24}\.[a-zA-Z0-9]{20}''' +keywords = [ + "pat.", + "sat.", +] + +[[rules]] +id = "hashicorp-tf-api-token" +description = "Uncovered a HashiCorp Terraform user/org API token, which may lead to unauthorized infrastructure management and security breaches." +regex = '''(?i)[a-z0-9]{14}\.(?-i:atlasv1)\.[a-z0-9\-_=]{60,70}''' +entropy = 3.5 +keywords = ["atlasv1"] + +[[rules]] +id = "hashicorp-tf-password" +description = "Identified a HashiCorp Terraform password field, risking unauthorized infrastructure configuration and security breaches." +regex = '''(?i)[\w.-]{0,50}?(?:administrator_login_password|password)(?:[ \t\w.-]{0,20})[\s'"]{0,3}(?:=|>|:{1,3}=|\|\||:|=>|\?=|,)[\x60'"\s=]{0,5}("[a-z0-9=_\-]{8,20}")(?:[\x60'"\s;]|\\[nr]|$)''' +path = '''(?i)\.(?:tf|hcl)$''' +entropy = 2 +keywords = [ + "administrator_login_password", + "password", +] + +[[rules]] +id = "heroku-api-key" +description = "Detected a Heroku API Key, potentially compromising cloud application deployments and operational security." +regex = '''(?i)[\w.-]{0,50}?(?:heroku)(?:[ \t\w.-]{0,20})[\s'"]{0,3}(?:=|>|:{1,3}=|\|\||:|=>|\?=|,)[\x60'"\s=]{0,5}([0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})(?:[\x60'"\s;]|\\[nr]|$)''' +keywords = ["heroku"] + +[[rules]] +id = "hubspot-api-key" +description = "Found a HubSpot API Token, posing a risk to CRM data integrity and unauthorized marketing operations." +regex = '''(?i)[\w.-]{0,50}?(?:hubspot)(?:[ \t\w.-]{0,20})[\s'"]{0,3}(?:=|>|:{1,3}=|\|\||:|=>|\?=|,)[\x60'"\s=]{0,5}([0-9A-F]{8}-[0-9A-F]{4}-[0-9A-F]{4}-[0-9A-F]{4}-[0-9A-F]{12})(?:[\x60'"\s;]|\\[nr]|$)''' +keywords = ["hubspot"] + +[[rules]] +id = "huggingface-access-token" +description = "Discovered a Hugging Face Access token, which could lead to unauthorized access to AI models and sensitive data." +regex = '''\b(hf_(?i:[a-z]{34}))(?:[\x60'"\s;]|\\[nr]|$)''' +entropy = 2 +keywords = ["hf_"] + +[[rules]] +id = "huggingface-organization-api-token" +description = "Uncovered a Hugging Face Organization API token, potentially compromising AI organization accounts and associated data." +regex = '''\b(api_org_(?i:[a-z]{34}))(?:[\x60'"\s;]|\\[nr]|$)''' +entropy = 2 +keywords = ["api_org_"] + +[[rules]] +id = "infracost-api-token" +description = "Detected an Infracost API Token, risking unauthorized access to cloud cost estimation tools and financial data." +regex = '''\b(ico-[a-zA-Z0-9]{32})(?:[\x60'"\s;]|\\[nr]|$)''' +entropy = 3 +keywords = ["ico-"] + +[[rules]] +id = "intercom-api-key" +description = "Identified an Intercom API Token, which could compromise customer communication channels and data privacy." +regex = '''(?i)[\w.-]{0,50}?(?:intercom)(?:[ \t\w.-]{0,20})[\s'"]{0,3}(?:=|>|:{1,3}=|\|\||:|=>|\?=|,)[\x60'"\s=]{0,5}([a-z0-9=_\-]{60})(?:[\x60'"\s;]|\\[nr]|$)''' +keywords = ["intercom"] + +[[rules]] +id = "intra42-client-secret" +description = "Found a Intra42 client secret, which could lead to unauthorized access to the 42School API and sensitive data." +regex = '''\b(s-s4t2(?:ud|af)-(?i)[abcdef0123456789]{64})(?:[\x60'"\s;]|\\[nr]|$)''' +entropy = 3 +keywords = [ + "intra", + "s-s4t2ud-", + "s-s4t2af-", +] + +[[rules]] +id = "jfrog-api-key" +description = "Found a JFrog API Key, posing a risk of unauthorized access to software artifact repositories and build pipelines." +regex = '''(?i)[\w.-]{0,50}?(?:jfrog|artifactory|bintray|xray)(?:[ \t\w.-]{0,20})[\s'"]{0,3}(?:=|>|:{1,3}=|\|\||:|=>|\?=|,)[\x60'"\s=]{0,5}([a-z0-9]{73})(?:[\x60'"\s;]|\\[nr]|$)''' +keywords = [ + "jfrog", + "artifactory", + "bintray", + "xray", +] + +[[rules]] +id = "jfrog-identity-token" +description = "Discovered a JFrog Identity Token, potentially compromising access to JFrog services and sensitive software artifacts." +regex = '''(?i)[\w.-]{0,50}?(?:jfrog|artifactory|bintray|xray)(?:[ \t\w.-]{0,20})[\s'"]{0,3}(?:=|>|:{1,3}=|\|\||:|=>|\?=|,)[\x60'"\s=]{0,5}([a-z0-9]{64})(?:[\x60'"\s;]|\\[nr]|$)''' +keywords = [ + "jfrog", + "artifactory", + "bintray", + "xray", +] + +[[rules]] +id = "jwt" +description = "Uncovered a JSON Web Token, which may lead to unauthorized access to web applications and sensitive user data." +regex = '''\b(ey[a-zA-Z0-9]{17,}\.ey[a-zA-Z0-9\/\\_-]{17,}\.(?:[a-zA-Z0-9\/\\_-]{10,}={0,2})?)(?:[\x60'"\s;]|\\[nr]|$)''' +entropy = 3 +keywords = ["ey"] + +[[rules]] +id = "jwt-base64" +description = "Detected a Base64-encoded JSON Web Token, posing a risk of exposing encoded authentication and data exchange information." +regex = '''\bZXlK(?:(?PaGJHY2lPaU)|(?PaGNIVWlPaU)|(?PaGNIWWlPaU)|(?PaGRXUWlPaU)|(?PaU5qUWlP)|(?PamNtbDBJanBi)|(?PamRIa2lPaU)|(?PbGNHc2lPbn)|(?PbGJtTWlPaU)|(?PcWEzVWlPaU)|(?PcWQyc2lPb)|(?PcGMzTWlPaU)|(?PcGRpSTZJ)|(?PcmFXUWlP)|(?PclpYbGZiM0J6SWpwY)|(?PcmRIa2lPaUp)|(?PdWIyNWpaU0k2)|(?Pd01tTWlP)|(?Pd01uTWlPaU)|(?Pd2NIUWlPaU)|(?PemRXSWlPaU)|(?PemRuUWlP)|(?PMFlXY2lPaU)|(?PMGVYQWlPaUp)|(?PMWNtd2l)|(?PMWMyVWlPaUp)|(?PMlpYSWlPaU)|(?PMlpYSnphVzl1SWpv)|(?PNElqb2)|(?PNE5XTWlP)|(?PNE5YUWlPaU)|(?PNE5YUWpVekkxTmlJNkl)|(?PNE5YVWlPaU)|(?PNmFYQWlPaU))[a-zA-Z0-9\/\\_+\-\r\n]{40,}={0,2}''' +entropy = 2 +keywords = ["zxlk"] + +[[rules]] +id = "kraken-access-token" +description = "Identified a Kraken Access Token, potentially compromising cryptocurrency trading accounts and financial security." +regex = '''(?i)[\w.-]{0,50}?(?:kraken)(?:[ \t\w.-]{0,20})[\s'"]{0,3}(?:=|>|:{1,3}=|\|\||:|=>|\?=|,)[\x60'"\s=]{0,5}([a-z0-9\/=_\+\-]{80,90})(?:[\x60'"\s;]|\\[nr]|$)''' +keywords = ["kraken"] + +[[rules]] +id = "kubernetes-secret-yaml" +description = "Possible Kubernetes Secret detected, posing a risk of leaking credentials/tokens from your deployments" +regex = '''(?i)(?:\bkind:[ \t]*["']?\bsecret\b["']?(?:.|\s){0,200}?\bdata:(?:.|\s){0,100}?\s+([\w.-]+:(?:[ \t]*(?:\||>[-+]?)\s+)?[ \t]*(?:["']?[a-z0-9+/]{10,}={0,3}["']?|\{\{[ \t\w"|$:=,.-]+}}|""|''))|\bdata:(?:.|\s){0,100}?\s+([\w.-]+:(?:[ \t]*(?:\||>[-+]?)\s+)?[ \t]*(?:["']?[a-z0-9+/]{10,}={0,3}["']?|\{\{[ \t\w"|$:=,.-]+}}|""|''))(?:.|\s){0,200}?\bkind:[ \t]*["']?\bsecret\b["']?)''' +path = '''(?i)\.ya?ml$''' +keywords = ["secret"] +[[rules.allowlists]] +regexes = [ + '''[\w.-]+:(?:[ \t]*(?:\||>[-+]?)\s+)?[ \t]*(?:\{\{[ \t\w"|$:=,.-]+}}|""|'')''', +] +[[rules.allowlists]] +regexTarget = "match" +regexes = [ + '''(kind:(?:.|\s)+\n---\n(?:.|\s)+\bdata:|data:(?:.|\s)+\n---\n(?:.|\s)+\bkind:)''', +] + +[[rules]] +id = "kucoin-access-token" +description = "Found a Kucoin Access Token, risking unauthorized access to cryptocurrency exchange services and transactions." +regex = '''(?i)[\w.-]{0,50}?(?:kucoin)(?:[ \t\w.-]{0,20})[\s'"]{0,3}(?:=|>|:{1,3}=|\|\||:|=>|\?=|,)[\x60'"\s=]{0,5}([a-f0-9]{24})(?:[\x60'"\s;]|\\[nr]|$)''' +keywords = ["kucoin"] + +[[rules]] +id = "kucoin-secret-key" +description = "Discovered a Kucoin Secret Key, which could lead to compromised cryptocurrency operations and financial data breaches." +regex = '''(?i)[\w.-]{0,50}?(?:kucoin)(?:[ \t\w.-]{0,20})[\s'"]{0,3}(?:=|>|:{1,3}=|\|\||:|=>|\?=|,)[\x60'"\s=]{0,5}([0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})(?:[\x60'"\s;]|\\[nr]|$)''' +keywords = ["kucoin"] + +[[rules]] +id = "launchdarkly-access-token" +description = "Uncovered a Launchdarkly Access Token, potentially compromising feature flag management and application functionality." +regex = '''(?i)[\w.-]{0,50}?(?:launchdarkly)(?:[ \t\w.-]{0,20})[\s'"]{0,3}(?:=|>|:{1,3}=|\|\||:|=>|\?=|,)[\x60'"\s=]{0,5}([a-z0-9=_\-]{40})(?:[\x60'"\s;]|\\[nr]|$)''' +keywords = ["launchdarkly"] + +[[rules]] +id = "linear-api-key" +description = "Detected a Linear API Token, posing a risk to project management tools and sensitive task data." +regex = '''lin_api_(?i)[a-z0-9]{40}''' +entropy = 2 +keywords = ["lin_api_"] + +[[rules]] +id = "linear-client-secret" +description = "Identified a Linear Client Secret, which may compromise secure integrations and sensitive project management data." +regex = '''(?i)[\w.-]{0,50}?(?:linear)(?:[ \t\w.-]{0,20})[\s'"]{0,3}(?:=|>|:{1,3}=|\|\||:|=>|\?=|,)[\x60'"\s=]{0,5}([a-f0-9]{32})(?:[\x60'"\s;]|\\[nr]|$)''' +entropy = 2 +keywords = ["linear"] + +[[rules]] +id = "linkedin-client-id" +description = "Found a LinkedIn Client ID, risking unauthorized access to LinkedIn integrations and professional data exposure." +regex = '''(?i)[\w.-]{0,50}?(?:linked[_-]?in)(?:[ \t\w.-]{0,20})[\s'"]{0,3}(?:=|>|:{1,3}=|\|\||:|=>|\?=|,)[\x60'"\s=]{0,5}([a-z0-9]{14})(?:[\x60'"\s;]|\\[nr]|$)''' +entropy = 2 +keywords = [ + "linkedin", + "linked_in", + "linked-in", +] + +[[rules]] +id = "linkedin-client-secret" +description = "Discovered a LinkedIn Client secret, potentially compromising LinkedIn application integrations and user data." +regex = '''(?i)[\w.-]{0,50}?(?:linked[_-]?in)(?:[ \t\w.-]{0,20})[\s'"]{0,3}(?:=|>|:{1,3}=|\|\||:|=>|\?=|,)[\x60'"\s=]{0,5}([a-z0-9]{16})(?:[\x60'"\s;]|\\[nr]|$)''' +entropy = 2 +keywords = [ + "linkedin", + "linked_in", + "linked-in", +] + +[[rules]] +id = "lob-api-key" +description = "Uncovered a Lob API Key, which could lead to unauthorized access to mailing and address verification services." +regex = '''(?i)[\w.-]{0,50}?(?:lob)(?:[ \t\w.-]{0,20})[\s'"]{0,3}(?:=|>|:{1,3}=|\|\||:|=>|\?=|,)[\x60'"\s=]{0,5}((live|test)_[a-f0-9]{35})(?:[\x60'"\s;]|\\[nr]|$)''' +keywords = [ + "test_", + "live_", +] + +[[rules]] +id = "lob-pub-api-key" +description = "Detected a Lob Publishable API Key, posing a risk of exposing mail and print service integrations." +regex = '''(?i)[\w.-]{0,50}?(?:lob)(?:[ \t\w.-]{0,20})[\s'"]{0,3}(?:=|>|:{1,3}=|\|\||:|=>|\?=|,)[\x60'"\s=]{0,5}((test|live)_pub_[a-f0-9]{31})(?:[\x60'"\s;]|\\[nr]|$)''' +keywords = [ + "test_pub", + "live_pub", + "_pub", +] + +[[rules]] +id = "mailchimp-api-key" +description = "Identified a Mailchimp API key, potentially compromising email marketing campaigns and subscriber data." +regex = '''(?i)[\w.-]{0,50}?(?:MailchimpSDK.initialize|mailchimp)(?:[ \t\w.-]{0,20})[\s'"]{0,3}(?:=|>|:{1,3}=|\|\||:|=>|\?=|,)[\x60'"\s=]{0,5}([a-f0-9]{32}-us\d\d)(?:[\x60'"\s;]|\\[nr]|$)''' +keywords = ["mailchimp"] + +[[rules]] +id = "mailgun-private-api-token" +description = "Found a Mailgun private API token, risking unauthorized email service operations and data breaches." +regex = '''(?i)[\w.-]{0,50}?(?:mailgun)(?:[ \t\w.-]{0,20})[\s'"]{0,3}(?:=|>|:{1,3}=|\|\||:|=>|\?=|,)[\x60'"\s=]{0,5}(key-[a-f0-9]{32})(?:[\x60'"\s;]|\\[nr]|$)''' +keywords = ["mailgun"] + +[[rules]] +id = "mailgun-pub-key" +description = "Discovered a Mailgun public validation key, which could expose email verification processes and associated data." +regex = '''(?i)[\w.-]{0,50}?(?:mailgun)(?:[ \t\w.-]{0,20})[\s'"]{0,3}(?:=|>|:{1,3}=|\|\||:|=>|\?=|,)[\x60'"\s=]{0,5}(pubkey-[a-f0-9]{32})(?:[\x60'"\s;]|\\[nr]|$)''' +keywords = ["mailgun"] + +[[rules]] +id = "mailgun-signing-key" +description = "Uncovered a Mailgun webhook signing key, potentially compromising email automation and data integrity." +regex = '''(?i)[\w.-]{0,50}?(?:mailgun)(?:[ \t\w.-]{0,20})[\s'"]{0,3}(?:=|>|:{1,3}=|\|\||:|=>|\?=|,)[\x60'"\s=]{0,5}([a-h0-9]{32}-[a-h0-9]{8}-[a-h0-9]{8})(?:[\x60'"\s;]|\\[nr]|$)''' +keywords = ["mailgun"] + +[[rules]] +id = "mapbox-api-token" +description = "Detected a MapBox API token, posing a risk to geospatial services and sensitive location data exposure." +regex = '''(?i)[\w.-]{0,50}?(?:mapbox)(?:[ \t\w.-]{0,20})[\s'"]{0,3}(?:=|>|:{1,3}=|\|\||:|=>|\?=|,)[\x60'"\s=]{0,5}(pk\.[a-z0-9]{60}\.[a-z0-9]{22})(?:[\x60'"\s;]|\\[nr]|$)''' +keywords = ["mapbox"] + +[[rules]] +id = "mattermost-access-token" +description = "Identified a Mattermost Access Token, which may compromise team communication channels and data privacy." +regex = '''(?i)[\w.-]{0,50}?(?:mattermost)(?:[ \t\w.-]{0,20})[\s'"]{0,3}(?:=|>|:{1,3}=|\|\||:|=>|\?=|,)[\x60'"\s=]{0,5}([a-z0-9]{26})(?:[\x60'"\s;]|\\[nr]|$)''' +keywords = ["mattermost"] + +[[rules]] +id = "maxmind-license-key" +description = "Discovered a potential MaxMind license key." +regex = '''\b([A-Za-z0-9]{6}_[A-Za-z0-9]{29}_mmk)(?:[\x60'"\s;]|\\[nr]|$)''' +entropy = 4 +keywords = ["_mmk"] + +[[rules]] +id = "messagebird-api-token" +description = "Found a MessageBird API token, risking unauthorized access to communication platforms and message data." +regex = '''(?i)[\w.-]{0,50}?(?:message[_-]?bird)(?:[ \t\w.-]{0,20})[\s'"]{0,3}(?:=|>|:{1,3}=|\|\||:|=>|\?=|,)[\x60'"\s=]{0,5}([a-z0-9]{25})(?:[\x60'"\s;]|\\[nr]|$)''' +keywords = [ + "messagebird", + "message-bird", + "message_bird", +] + +[[rules]] +id = "messagebird-client-id" +description = "Discovered a MessageBird client ID, potentially compromising API integrations and sensitive communication data." +regex = '''(?i)[\w.-]{0,50}?(?:message[_-]?bird)(?:[ \t\w.-]{0,20})[\s'"]{0,3}(?:=|>|:{1,3}=|\|\||:|=>|\?=|,)[\x60'"\s=]{0,5}([0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})(?:[\x60'"\s;]|\\[nr]|$)''' +keywords = [ + "messagebird", + "message-bird", + "message_bird", +] + +[[rules]] +id = "microsoft-teams-webhook" +description = "Uncovered a Microsoft Teams Webhook, which could lead to unauthorized access to team collaboration tools and data leaks." +regex = '''https://[a-z0-9]+\.webhook\.office\.com/webhookb2/[a-z0-9]{8}-([a-z0-9]{4}-){3}[a-z0-9]{12}@[a-z0-9]{8}-([a-z0-9]{4}-){3}[a-z0-9]{12}/IncomingWebhook/[a-z0-9]{32}/[a-z0-9]{8}-([a-z0-9]{4}-){3}[a-z0-9]{12}''' +keywords = [ + "webhook.office.com", + "webhookb2", + "incomingwebhook", +] + +[[rules]] +id = "netlify-access-token" +description = "Detected a Netlify Access Token, potentially compromising web hosting services and site management." +regex = '''(?i)[\w.-]{0,50}?(?:netlify)(?:[ \t\w.-]{0,20})[\s'"]{0,3}(?:=|>|:{1,3}=|\|\||:|=>|\?=|,)[\x60'"\s=]{0,5}([a-z0-9=_\-]{40,46})(?:[\x60'"\s;]|\\[nr]|$)''' +keywords = ["netlify"] + +[[rules]] +id = "new-relic-browser-api-token" +description = "Identified a New Relic ingest browser API token, risking unauthorized access to application performance data and analytics." +regex = '''(?i)[\w.-]{0,50}?(?:new-relic|newrelic|new_relic)(?:[ \t\w.-]{0,20})[\s'"]{0,3}(?:=|>|:{1,3}=|\|\||:|=>|\?=|,)[\x60'"\s=]{0,5}(NRJS-[a-f0-9]{19})(?:[\x60'"\s;]|\\[nr]|$)''' +keywords = ["nrjs-"] + +[[rules]] +id = "new-relic-insert-key" +description = "Discovered a New Relic insight insert key, compromising data injection into the platform." +regex = '''(?i)[\w.-]{0,50}?(?:new-relic|newrelic|new_relic)(?:[ \t\w.-]{0,20})[\s'"]{0,3}(?:=|>|:{1,3}=|\|\||:|=>|\?=|,)[\x60'"\s=]{0,5}(NRII-[a-z0-9-]{32})(?:[\x60'"\s;]|\\[nr]|$)''' +keywords = ["nrii-"] + +[[rules]] +id = "new-relic-user-api-id" +description = "Found a New Relic user API ID, posing a risk to application monitoring services and data integrity." +regex = '''(?i)[\w.-]{0,50}?(?:new-relic|newrelic|new_relic)(?:[ \t\w.-]{0,20})[\s'"]{0,3}(?:=|>|:{1,3}=|\|\||:|=>|\?=|,)[\x60'"\s=]{0,5}([a-z0-9]{64})(?:[\x60'"\s;]|\\[nr]|$)''' +keywords = [ + "new-relic", + "newrelic", + "new_relic", +] + +[[rules]] +id = "new-relic-user-api-key" +description = "Discovered a New Relic user API Key, which could lead to compromised application insights and performance monitoring." +regex = '''(?i)[\w.-]{0,50}?(?:new-relic|newrelic|new_relic)(?:[ \t\w.-]{0,20})[\s'"]{0,3}(?:=|>|:{1,3}=|\|\||:|=>|\?=|,)[\x60'"\s=]{0,5}(NRAK-[a-z0-9]{27})(?:[\x60'"\s;]|\\[nr]|$)''' +keywords = ["nrak"] + +[[rules]] +id = "npm-access-token" +description = "Uncovered an npm access token, potentially compromising package management and code repository access." +regex = '''(?i)\b(npm_[a-z0-9]{36})(?:[\x60'"\s;]|\\[nr]|$)''' +entropy = 2 +keywords = ["npm_"] + +[[rules]] +id = "nuget-config-password" +description = "Identified a password within a Nuget config file, potentially compromising package management access." +regex = '''(?i)''' +path = '''(?i)nuget\.config$''' +entropy = 1 +keywords = ["|:{1,3}=|\|\||:|=>|\?=|,)[\x60'"\s=]{0,5}([a-z0-9=_\-]{32})(?:[\x60'"\s;]|\\[nr]|$)''' +keywords = [ + "nytimes", + "new-york-times", + "newyorktimes", +] + +[[rules]] +id = "octopus-deploy-api-key" +description = "Discovered a potential Octopus Deploy API key, risking application deployments and operational security." +regex = '''\b(API-[A-Z0-9]{26})(?:[\x60'"\s;]|\\[nr]|$)''' +entropy = 3 +keywords = ["api-"] + +[[rules]] +id = "okta-access-token" +description = "Identified an Okta Access Token, which may compromise identity management services and user authentication data." +regex = '''[\w.-]{0,50}?(?i:[\w.-]{0,50}?(?:(?-i:[Oo]kta|OKTA))(?:[ \t\w.-]{0,20})[\s'"]{0,3})(?:=|>|:{1,3}=|\|\||:|=>|\?=|,)[\x60'"\s=]{0,5}(00[\w=\-]{40})(?:[\x60'"\s;]|\\[nr]|$)''' +entropy = 4 +keywords = ["okta"] + +[[rules]] +id = "openai-api-key" +description = "Found an OpenAI API Key, posing a risk of unauthorized access to AI services and data manipulation." +regex = '''\b(sk-(?:proj|svcacct|admin)-(?:[A-Za-z0-9_-]{74}|[A-Za-z0-9_-]{58})T3BlbkFJ(?:[A-Za-z0-9_-]{74}|[A-Za-z0-9_-]{58})\b|sk-[a-zA-Z0-9]{20}T3BlbkFJ[a-zA-Z0-9]{20})(?:[\x60'"\s;]|\\[nr]|$)''' +entropy = 3 +keywords = ["t3blbkfj"] + +[[rules]] +id = "openshift-user-token" +description = "Found an OpenShift user token, potentially compromising an OpenShift/Kubernetes cluster." +regex = '''\b(sha256~[\w-]{43})(?:[^\w-]|\z)''' +entropy = 3.5 +keywords = ["sha256~"] + +[[rules]] +id = "pkcs12-file" +description = "Found a PKCS #12 file, which commonly contain bundled private keys." +path = '''(?i)(?:^|\/)[^\/]+\.p(?:12|fx)$''' + +[[rules]] +id = "plaid-api-token" +description = "Discovered a Plaid API Token, potentially compromising financial data aggregation and banking services." +regex = '''(?i)[\w.-]{0,50}?(?:plaid)(?:[ \t\w.-]{0,20})[\s'"]{0,3}(?:=|>|:{1,3}=|\|\||:|=>|\?=|,)[\x60'"\s=]{0,5}(access-(?:sandbox|development|production)-[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})(?:[\x60'"\s;]|\\[nr]|$)''' +keywords = ["plaid"] + +[[rules]] +id = "plaid-client-id" +description = "Uncovered a Plaid Client ID, which could lead to unauthorized financial service integrations and data breaches." +regex = '''(?i)[\w.-]{0,50}?(?:plaid)(?:[ \t\w.-]{0,20})[\s'"]{0,3}(?:=|>|:{1,3}=|\|\||:|=>|\?=|,)[\x60'"\s=]{0,5}([a-z0-9]{24})(?:[\x60'"\s;]|\\[nr]|$)''' +entropy = 3.5 +keywords = ["plaid"] + +[[rules]] +id = "plaid-secret-key" +description = "Detected a Plaid Secret key, risking unauthorized access to financial accounts and sensitive transaction data." +regex = '''(?i)[\w.-]{0,50}?(?:plaid)(?:[ \t\w.-]{0,20})[\s'"]{0,3}(?:=|>|:{1,3}=|\|\||:|=>|\?=|,)[\x60'"\s=]{0,5}([a-z0-9]{30})(?:[\x60'"\s;]|\\[nr]|$)''' +entropy = 3.5 +keywords = ["plaid"] + +[[rules]] +id = "planetscale-api-token" +description = "Identified a PlanetScale API token, potentially compromising database management and operations." +regex = '''\b(pscale_tkn_(?i)[\w=\.-]{32,64})(?:[\x60'"\s;]|\\[nr]|$)''' +entropy = 3 +keywords = ["pscale_tkn_"] + +[[rules]] +id = "planetscale-oauth-token" +description = "Found a PlanetScale OAuth token, posing a risk to database access control and sensitive data integrity." +regex = '''\b(pscale_oauth_[\w=\.-]{32,64})(?:[\x60'"\s;]|\\[nr]|$)''' +entropy = 3 +keywords = ["pscale_oauth_"] + +[[rules]] +id = "planetscale-password" +description = "Discovered a PlanetScale password, which could lead to unauthorized database operations and data breaches." +regex = '''(?i)\b(pscale_pw_(?i)[\w=\.-]{32,64})(?:[\x60'"\s;]|\\[nr]|$)''' +entropy = 3 +keywords = ["pscale_pw_"] + +[[rules]] +id = "postman-api-token" +description = "Uncovered a Postman API token, potentially compromising API testing and development workflows." +regex = '''\b(PMAK-(?i)[a-f0-9]{24}\-[a-f0-9]{34})(?:[\x60'"\s;]|\\[nr]|$)''' +entropy = 3 +keywords = ["pmak-"] + +[[rules]] +id = "prefect-api-token" +description = "Detected a Prefect API token, risking unauthorized access to workflow management and automation services." +regex = '''\b(pnu_[a-zA-Z0-9]{36})(?:[\x60'"\s;]|\\[nr]|$)''' +entropy = 2 +keywords = ["pnu_"] + +[[rules]] +id = "private-key" +description = "Identified a Private Key, which may compromise cryptographic security and sensitive data encryption." +regex = '''(?i)-----BEGIN[ A-Z0-9_-]{0,100}PRIVATE KEY(?: BLOCK)?-----[\s\S-]{64,}?KEY(?: BLOCK)?-----''' +keywords = ["-----begin"] + +[[rules]] +id = "privateai-api-token" +description = "Identified a PrivateAI Token, posing a risk of unauthorized access to AI services and data manipulation." +regex = '''[\w.-]{0,50}?(?i:[\w.-]{0,50}?(?:private[_-]?ai)(?:[ \t\w.-]{0,20})[\s'"]{0,3})(?:=|>|:{1,3}=|\|\||:|=>|\?=|,)[\x60'"\s=]{0,5}([a-z0-9]{32})(?:[\x60'"\s;]|\\[nr]|$)''' +entropy = 3 +keywords = [ + "privateai", + "private_ai", + "private-ai", +] + +[[rules]] +id = "pulumi-api-token" +description = "Found a Pulumi API token, posing a risk to infrastructure as code services and cloud resource management." +regex = '''\b(pul-[a-f0-9]{40})(?:[\x60'"\s;]|\\[nr]|$)''' +entropy = 2 +keywords = ["pul-"] + +[[rules]] +id = "pypi-upload-token" +description = "Discovered a PyPI upload token, potentially compromising Python package distribution and repository integrity." +regex = '''pypi-AgEIcHlwaS5vcmc[\w-]{50,1000}''' +entropy = 3 +keywords = ["pypi-ageichlwas5vcmc"] + +[[rules]] +id = "rapidapi-access-token" +description = "Uncovered a RapidAPI Access Token, which could lead to unauthorized access to various APIs and data services." +regex = '''(?i)[\w.-]{0,50}?(?:rapidapi)(?:[ \t\w.-]{0,20})[\s'"]{0,3}(?:=|>|:{1,3}=|\|\||:|=>|\?=|,)[\x60'"\s=]{0,5}([a-z0-9_-]{50})(?:[\x60'"\s;]|\\[nr]|$)''' +keywords = ["rapidapi"] + +[[rules]] +id = "readme-api-token" +description = "Detected a Readme API token, risking unauthorized documentation management and content exposure." +regex = '''\b(rdme_[a-z0-9]{70})(?:[\x60'"\s;]|\\[nr]|$)''' +entropy = 2 +keywords = ["rdme_"] + +[[rules]] +id = "rubygems-api-token" +description = "Identified a Rubygem API token, potentially compromising Ruby library distribution and package management." +regex = '''\b(rubygems_[a-f0-9]{48})(?:[\x60'"\s;]|\\[nr]|$)''' +entropy = 2 +keywords = ["rubygems_"] + +[[rules]] +id = "scalingo-api-token" +description = "Found a Scalingo API token, posing a risk to cloud platform services and application deployment security." +regex = '''\b(tk-us-[\w-]{48})(?:[\x60'"\s;]|\\[nr]|$)''' +entropy = 2 +keywords = ["tk-us-"] + +[[rules]] +id = "sendbird-access-id" +description = "Discovered a Sendbird Access ID, which could compromise chat and messaging platform integrations." +regex = '''(?i)[\w.-]{0,50}?(?:sendbird)(?:[ \t\w.-]{0,20})[\s'"]{0,3}(?:=|>|:{1,3}=|\|\||:|=>|\?=|,)[\x60'"\s=]{0,5}([0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})(?:[\x60'"\s;]|\\[nr]|$)''' +keywords = ["sendbird"] + +[[rules]] +id = "sendbird-access-token" +description = "Uncovered a Sendbird Access Token, potentially risking unauthorized access to communication services and user data." +regex = '''(?i)[\w.-]{0,50}?(?:sendbird)(?:[ \t\w.-]{0,20})[\s'"]{0,3}(?:=|>|:{1,3}=|\|\||:|=>|\?=|,)[\x60'"\s=]{0,5}([a-f0-9]{40})(?:[\x60'"\s;]|\\[nr]|$)''' +keywords = ["sendbird"] + +[[rules]] +id = "sendgrid-api-token" +description = "Detected a SendGrid API token, posing a risk of unauthorized email service operations and data exposure." +regex = '''\b(SG\.(?i)[a-z0-9=_\-\.]{66})(?:[\x60'"\s;]|\\[nr]|$)''' +entropy = 2 +keywords = ["sg."] + +[[rules]] +id = "sendinblue-api-token" +description = "Identified a Sendinblue API token, which may compromise email marketing services and subscriber data privacy." +regex = '''\b(xkeysib-[a-f0-9]{64}\-(?i)[a-z0-9]{16})(?:[\x60'"\s;]|\\[nr]|$)''' +entropy = 2 +keywords = ["xkeysib-"] + +[[rules]] +id = "sentry-access-token" +description = "Found a Sentry.io Access Token (old format), risking unauthorized access to error tracking services and sensitive application data." +regex = '''(?i)[\w.-]{0,50}?(?:sentry)(?:[ \t\w.-]{0,20})[\s'"]{0,3}(?:=|>|:{1,3}=|\|\||:|=>|\?=|,)[\x60'"\s=]{0,5}([a-f0-9]{64})(?:[\x60'"\s;]|\\[nr]|$)''' +entropy = 3 +keywords = ["sentry"] + +[[rules]] +id = "sentry-org-token" +description = "Found a Sentry.io Organization Token, risking unauthorized access to error tracking services and sensitive application data." +regex = '''\bsntrys_eyJpYXQiO[a-zA-Z0-9+/]{10,200}(?:LCJyZWdpb25fdXJs|InJlZ2lvbl91cmwi|cmVnaW9uX3VybCI6)[a-zA-Z0-9+/]{10,200}={0,2}_[a-zA-Z0-9+/]{43}(?:[^a-zA-Z0-9+/]|\z)''' +entropy = 4.5 +keywords = ["sntrys_eyjpyxqio"] + +[[rules]] +id = "sentry-user-token" +description = "Found a Sentry.io User Token, risking unauthorized access to error tracking services and sensitive application data." +regex = '''\b(sntryu_[a-f0-9]{64})(?:[\x60'"\s;]|\\[nr]|$)''' +entropy = 3.5 +keywords = ["sntryu_"] + +[[rules]] +id = "settlemint-application-access-token" +description = "Found a Settlemint Application Access Token." +regex = '''\b(sm_aat_[a-zA-Z0-9]{16})(?:[\x60'"\s;]|\\[nr]|$)''' +entropy = 3 +keywords = ["sm_aat"] + +[[rules]] +id = "settlemint-personal-access-token" +description = "Found a Settlemint Personal Access Token." +regex = '''\b(sm_pat_[a-zA-Z0-9]{16})(?:[\x60'"\s;]|\\[nr]|$)''' +entropy = 3 +keywords = ["sm_pat"] + +[[rules]] +id = "settlemint-service-access-token" +description = "Found a Settlemint Service Access Token." +regex = '''\b(sm_sat_[a-zA-Z0-9]{16})(?:[\x60'"\s;]|\\[nr]|$)''' +entropy = 3 +keywords = ["sm_sat"] + +[[rules]] +id = "shippo-api-token" +description = "Discovered a Shippo API token, potentially compromising shipping services and customer order data." +regex = '''\b(shippo_(?:live|test)_[a-fA-F0-9]{40})(?:[\x60'"\s;]|\\[nr]|$)''' +entropy = 2 +keywords = ["shippo_"] + +[[rules]] +id = "shopify-access-token" +description = "Uncovered a Shopify access token, which could lead to unauthorized e-commerce platform access and data breaches." +regex = '''shpat_[a-fA-F0-9]{32}''' +entropy = 2 +keywords = ["shpat_"] + +[[rules]] +id = "shopify-custom-access-token" +description = "Detected a Shopify custom access token, potentially compromising custom app integrations and e-commerce data security." +regex = '''shpca_[a-fA-F0-9]{32}''' +entropy = 2 +keywords = ["shpca_"] + +[[rules]] +id = "shopify-private-app-access-token" +description = "Identified a Shopify private app access token, risking unauthorized access to private app data and store operations." +regex = '''shppa_[a-fA-F0-9]{32}''' +entropy = 2 +keywords = ["shppa_"] + +[[rules]] +id = "shopify-shared-secret" +description = "Found a Shopify shared secret, posing a risk to application authentication and e-commerce platform security." +regex = '''shpss_[a-fA-F0-9]{32}''' +entropy = 2 +keywords = ["shpss_"] + +[[rules]] +id = "sidekiq-secret" +description = "Discovered a Sidekiq Secret, which could lead to compromised background job processing and application data breaches." +regex = '''(?i)[\w.-]{0,50}?(?:BUNDLE_ENTERPRISE__CONTRIBSYS__COM|BUNDLE_GEMS__CONTRIBSYS__COM)(?:[ \t\w.-]{0,20})[\s'"]{0,3}(?:=|>|:{1,3}=|\|\||:|=>|\?=|,)[\x60'"\s=]{0,5}([a-f0-9]{8}:[a-f0-9]{8})(?:[\x60'"\s;]|\\[nr]|$)''' +keywords = [ + "bundle_enterprise__contribsys__com", + "bundle_gems__contribsys__com", +] + +[[rules]] +id = "sidekiq-sensitive-url" +description = "Uncovered a Sidekiq Sensitive URL, potentially exposing internal job queues and sensitive operation details." +regex = '''(?i)\bhttps?://([a-f0-9]{8}:[a-f0-9]{8})@(?:gems.contribsys.com|enterprise.contribsys.com)(?:[\/|\#|\?|:]|$)''' +keywords = [ + "gems.contribsys.com", + "enterprise.contribsys.com", +] + +[[rules]] +id = "slack-app-token" +description = "Detected a Slack App-level token, risking unauthorized access to Slack applications and workspace data." +regex = '''(?i)xapp-\d-[A-Z0-9]+-\d+-[a-z0-9]+''' +entropy = 2 +keywords = ["xapp"] + +[[rules]] +id = "slack-bot-token" +description = "Identified a Slack Bot token, which may compromise bot integrations and communication channel security." +regex = '''xoxb-[0-9]{10,13}-[0-9]{10,13}[a-zA-Z0-9-]*''' +entropy = 3 +keywords = ["xoxb"] + +[[rules]] +id = "slack-config-access-token" +description = "Found a Slack Configuration access token, posing a risk to workspace configuration and sensitive data access." +regex = '''(?i)xoxe.xox[bp]-\d-[A-Z0-9]{163,166}''' +entropy = 2 +keywords = [ + "xoxe.xoxb-", + "xoxe.xoxp-", +] + +[[rules]] +id = "slack-config-refresh-token" +description = "Discovered a Slack Configuration refresh token, potentially allowing prolonged unauthorized access to configuration settings." +regex = '''(?i)xoxe-\d-[A-Z0-9]{146}''' +entropy = 2 +keywords = ["xoxe-"] + +[[rules]] +id = "slack-legacy-bot-token" +description = "Uncovered a Slack Legacy bot token, which could lead to compromised legacy bot operations and data exposure." +regex = '''xoxb-[0-9]{8,14}-[a-zA-Z0-9]{18,26}''' +entropy = 2 +keywords = ["xoxb"] + +[[rules]] +id = "slack-legacy-token" +description = "Detected a Slack Legacy token, risking unauthorized access to older Slack integrations and user data." +regex = '''xox[os]-\d+-\d+-\d+-[a-fA-F\d]+''' +entropy = 2 +keywords = [ + "xoxo", + "xoxs", +] + +[[rules]] +id = "slack-legacy-workspace-token" +description = "Identified a Slack Legacy Workspace token, potentially compromising access to workspace data and legacy features." +regex = '''xox[ar]-(?:\d-)?[0-9a-zA-Z]{8,48}''' +entropy = 2 +keywords = [ + "xoxa", + "xoxr", +] + +[[rules]] +id = "slack-user-token" +description = "Found a Slack User token, posing a risk of unauthorized user impersonation and data access within Slack workspaces." +regex = '''xox[pe](?:-[0-9]{10,13}){3}-[a-zA-Z0-9-]{28,34}''' +entropy = 2 +keywords = [ + "xoxp-", + "xoxe-", +] + +[[rules]] +id = "slack-webhook-url" +description = "Discovered a Slack Webhook, which could lead to unauthorized message posting and data leakage in Slack channels." +regex = '''(?:https?://)?hooks.slack.com/(?:services|workflows|triggers)/[A-Za-z0-9+/]{43,56}''' +keywords = ["hooks.slack.com"] + +[[rules]] +id = "snyk-api-token" +description = "Uncovered a Snyk API token, potentially compromising software vulnerability scanning and code security." +regex = '''(?i)[\w.-]{0,50}?(?:snyk[_.-]?(?:(?:api|oauth)[_.-]?)?(?:key|token))(?:[ \t\w.-]{0,20})[\s'"]{0,3}(?:=|>|:{1,3}=|\|\||:|=>|\?=|,)[\x60'"\s=]{0,5}([0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})(?:[\x60'"\s;]|\\[nr]|$)''' +keywords = ["snyk"] + +[[rules]] +id = "sonar-api-token" +description = "Uncovered a Sonar API token, potentially compromising software vulnerability scanning and code security." +regex = '''(?i)[\w.-]{0,50}?(?:sonar[_.-]?(login|token))(?:[ \t\w.-]{0,20})[\s'"]{0,3}(?:=|>|:{1,3}=|\|\||:|=>|\?=|,)[\x60'"\s=]{0,5}([a-z0-9=_\-]{40})(?:[\x60'"\s;]|\\[nr]|$)''' +keywords = ["sonar"] + +[[rules]] +id = "sourcegraph-access-token" +description = "Sourcegraph is a code search and navigation engine." +regex = '''(?i)\b(\b(sgp_(?:[a-fA-F0-9]{16}|local)_[a-fA-F0-9]{40}|sgp_[a-fA-F0-9]{40}|[a-fA-F0-9]{40})\b)(?:[\x60'"\s;]|\\[nr]|$)''' +entropy = 3 +keywords = [ + "sgp_", + "sourcegraph", +] + +[[rules]] +id = "square-access-token" +description = "Detected a Square Access Token, risking unauthorized payment processing and financial transaction exposure." +regex = '''\b((?:EAAA|sq0atp-)[\w-]{22,60})(?:[\x60'"\s;]|\\[nr]|$)''' +entropy = 2 +keywords = [ + "sq0atp-", + "eaaa", +] + +[[rules]] +id = "squarespace-access-token" +description = "Identified a Squarespace Access Token, which may compromise website management and content control on Squarespace." +regex = '''(?i)[\w.-]{0,50}?(?:squarespace)(?:[ \t\w.-]{0,20})[\s'"]{0,3}(?:=|>|:{1,3}=|\|\||:|=>|\?=|,)[\x60'"\s=]{0,5}([0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})(?:[\x60'"\s;]|\\[nr]|$)''' +keywords = ["squarespace"] + +[[rules]] +id = "stripe-access-token" +description = "Found a Stripe Access Token, posing a risk to payment processing services and sensitive financial data." +regex = '''\b((?:sk|rk)_(?:test|live|prod)_[a-zA-Z0-9]{10,99})(?:[\x60'"\s;]|\\[nr]|$)''' +entropy = 2 +keywords = [ + "sk_test", + "sk_live", + "sk_prod", + "rk_test", + "rk_live", + "rk_prod", +] + +[[rules]] +id = "sumologic-access-id" +description = "Discovered a SumoLogic Access ID, potentially compromising log management services and data analytics integrity." +regex = '''[\w.-]{0,50}?(?i:[\w.-]{0,50}?(?:(?-i:[Ss]umo|SUMO))(?:[ \t\w.-]{0,20})[\s'"]{0,3})(?:=|>|:{1,3}=|\|\||:|=>|\?=|,)[\x60'"\s=]{0,5}(su[a-zA-Z0-9]{12})(?:[\x60'"\s;]|\\[nr]|$)''' +entropy = 3 +keywords = ["sumo"] + +[[rules]] +id = "sumologic-access-token" +description = "Uncovered a SumoLogic Access Token, which could lead to unauthorized access to log data and analytics insights." +regex = '''(?i)[\w.-]{0,50}?(?:(?-i:[Ss]umo|SUMO))(?:[ \t\w.-]{0,20})[\s'"]{0,3}(?:=|>|:{1,3}=|\|\||:|=>|\?=|,)[\x60'"\s=]{0,5}([a-z0-9]{64})(?:[\x60'"\s;]|\\[nr]|$)''' +entropy = 3 +keywords = ["sumo"] + +[[rules]] +id = "telegram-bot-api-token" +description = "Detected a Telegram Bot API Token, risking unauthorized bot operations and message interception on Telegram." +regex = '''(?i)[\w.-]{0,50}?(?:telegr)(?:[ \t\w.-]{0,20})[\s'"]{0,3}(?:=|>|:{1,3}=|\|\||:|=>|\?=|,)[\x60'"\s=]{0,5}([0-9]{5,16}:(?-i:A)[a-z0-9_\-]{34})(?:[\x60'"\s;]|\\[nr]|$)''' +keywords = ["telegr"] + +[[rules]] +id = "travisci-access-token" +description = "Identified a Travis CI Access Token, potentially compromising continuous integration services and codebase security." +regex = '''(?i)[\w.-]{0,50}?(?:travis)(?:[ \t\w.-]{0,20})[\s'"]{0,3}(?:=|>|:{1,3}=|\|\||:|=>|\?=|,)[\x60'"\s=]{0,5}([a-z0-9]{22})(?:[\x60'"\s;]|\\[nr]|$)''' +keywords = ["travis"] + +[[rules]] +id = "twilio-api-key" +description = "Found a Twilio API Key, posing a risk to communication services and sensitive customer interaction data." +regex = '''SK[0-9a-fA-F]{32}''' +entropy = 3 +keywords = ["sk"] + +[[rules]] +id = "twitch-api-token" +description = "Discovered a Twitch API token, which could compromise streaming services and account integrations." +regex = '''(?i)[\w.-]{0,50}?(?:twitch)(?:[ \t\w.-]{0,20})[\s'"]{0,3}(?:=|>|:{1,3}=|\|\||:|=>|\?=|,)[\x60'"\s=]{0,5}([a-z0-9]{30})(?:[\x60'"\s;]|\\[nr]|$)''' +keywords = ["twitch"] + +[[rules]] +id = "twitter-access-secret" +description = "Uncovered a Twitter Access Secret, potentially risking unauthorized Twitter integrations and data breaches." +regex = '''(?i)[\w.-]{0,50}?(?:twitter)(?:[ \t\w.-]{0,20})[\s'"]{0,3}(?:=|>|:{1,3}=|\|\||:|=>|\?=|,)[\x60'"\s=]{0,5}([a-z0-9]{45})(?:[\x60'"\s;]|\\[nr]|$)''' +keywords = ["twitter"] + +[[rules]] +id = "twitter-access-token" +description = "Detected a Twitter Access Token, posing a risk of unauthorized account operations and social media data exposure." +regex = '''(?i)[\w.-]{0,50}?(?:twitter)(?:[ \t\w.-]{0,20})[\s'"]{0,3}(?:=|>|:{1,3}=|\|\||:|=>|\?=|,)[\x60'"\s=]{0,5}([0-9]{15,25}-[a-zA-Z0-9]{20,40})(?:[\x60'"\s;]|\\[nr]|$)''' +keywords = ["twitter"] + +[[rules]] +id = "twitter-api-key" +description = "Identified a Twitter API Key, which may compromise Twitter application integrations and user data security." +regex = '''(?i)[\w.-]{0,50}?(?:twitter)(?:[ \t\w.-]{0,20})[\s'"]{0,3}(?:=|>|:{1,3}=|\|\||:|=>|\?=|,)[\x60'"\s=]{0,5}([a-z0-9]{25})(?:[\x60'"\s;]|\\[nr]|$)''' +keywords = ["twitter"] + +[[rules]] +id = "twitter-api-secret" +description = "Found a Twitter API Secret, risking the security of Twitter app integrations and sensitive data access." +regex = '''(?i)[\w.-]{0,50}?(?:twitter)(?:[ \t\w.-]{0,20})[\s'"]{0,3}(?:=|>|:{1,3}=|\|\||:|=>|\?=|,)[\x60'"\s=]{0,5}([a-z0-9]{50})(?:[\x60'"\s;]|\\[nr]|$)''' +keywords = ["twitter"] + +[[rules]] +id = "twitter-bearer-token" +description = "Discovered a Twitter Bearer Token, potentially compromising API access and data retrieval from Twitter." +regex = '''(?i)[\w.-]{0,50}?(?:twitter)(?:[ \t\w.-]{0,20})[\s'"]{0,3}(?:=|>|:{1,3}=|\|\||:|=>|\?=|,)[\x60'"\s=]{0,5}(A{22}[a-zA-Z0-9%]{80,100})(?:[\x60'"\s;]|\\[nr]|$)''' +keywords = ["twitter"] + +[[rules]] +id = "typeform-api-token" +description = "Uncovered a Typeform API token, which could lead to unauthorized survey management and data collection." +regex = '''(?i)[\w.-]{0,50}?(?:typeform)(?:[ \t\w.-]{0,20})[\s'"]{0,3}(?:=|>|:{1,3}=|\|\||:|=>|\?=|,)[\x60'"\s=]{0,5}(tfp_[a-z0-9\-_\.=]{59})(?:[\x60'"\s;]|\\[nr]|$)''' +keywords = ["tfp_"] + +[[rules]] +id = "vault-batch-token" +description = "Detected a Vault Batch Token, risking unauthorized access to secret management services and sensitive data." +regex = '''\b(hvb\.[\w-]{138,300})(?:[\x60'"\s;]|\\[nr]|$)''' +entropy = 4 +keywords = ["hvb."] + +[[rules]] +id = "vault-service-token" +description = "Identified a Vault Service Token, potentially compromising infrastructure security and access to sensitive credentials." +regex = '''\b((?:hvs\.[\w-]{90,120}|s\.(?i:[a-z0-9]{24})))(?:[\x60'"\s;]|\\[nr]|$)''' +entropy = 3.5 +keywords = [ + "hvs.", + "s.", +] +[[rules.allowlists]] +regexes = [ + '''s\.[A-Za-z]{24}''', +] + +[[rules]] +id = "yandex-access-token" +description = "Found a Yandex Access Token, posing a risk to Yandex service integrations and user data privacy." +regex = '''(?i)[\w.-]{0,50}?(?:yandex)(?:[ \t\w.-]{0,20})[\s'"]{0,3}(?:=|>|:{1,3}=|\|\||:|=>|\?=|,)[\x60'"\s=]{0,5}(t1\.[A-Z0-9a-z_-]+[=]{0,2}\.[A-Z0-9a-z_-]{86}[=]{0,2})(?:[\x60'"\s;]|\\[nr]|$)''' +keywords = ["yandex"] + +[[rules]] +id = "yandex-api-key" +description = "Discovered a Yandex API Key, which could lead to unauthorized access to Yandex services and data manipulation." +regex = '''(?i)[\w.-]{0,50}?(?:yandex)(?:[ \t\w.-]{0,20})[\s'"]{0,3}(?:=|>|:{1,3}=|\|\||:|=>|\?=|,)[\x60'"\s=]{0,5}(AQVN[A-Za-z0-9_\-]{35,38})(?:[\x60'"\s;]|\\[nr]|$)''' +keywords = ["yandex"] + +[[rules]] +id = "yandex-aws-access-token" +description = "Uncovered a Yandex AWS Access Token, potentially compromising cloud resource access and data security on Yandex Cloud." +regex = '''(?i)[\w.-]{0,50}?(?:yandex)(?:[ \t\w.-]{0,20})[\s'"]{0,3}(?:=|>|:{1,3}=|\|\||:|=>|\?=|,)[\x60'"\s=]{0,5}(YC[a-zA-Z0-9_\-]{38})(?:[\x60'"\s;]|\\[nr]|$)''' +keywords = ["yandex"] + +[[rules]] +id = "zendesk-secret-key" +description = "Detected a Zendesk Secret Key, risking unauthorized access to customer support services and sensitive ticketing data." +regex = '''(?i)[\w.-]{0,50}?(?:zendesk)(?:[ \t\w.-]{0,20})[\s'"]{0,3}(?:=|>|:{1,3}=|\|\||:|=>|\?=|,)[\x60'"\s=]{0,5}([a-z0-9]{40})(?:[\x60'"\s;]|\\[nr]|$)''' +keywords = ["zendesk"] diff --git a/common/src/main/java/com/skyflow/errors/ErrorMessage.java b/common/src/main/java/com/skyflow/errors/ErrorMessage.java index f4b2ce7b..459998ab 100644 --- a/common/src/main/java/com/skyflow/errors/ErrorMessage.java +++ b/common/src/main/java/com/skyflow/errors/ErrorMessage.java @@ -16,6 +16,8 @@ public enum ErrorMessage { EmptyVaultId("%s0 Initialization failed. Invalid vault ID. Vault ID must not be empty."), InvalidClusterId("%s0 Initialization failed. Invalid cluster ID. Specify cluster ID."), EmptyClusterId("%s0 Initialization failed. Invalid cluster ID. Specify a valid cluster ID."), + EmptyVaultUrl("%s0 Initialization failed. Vault URL is empty. Specify a valid vault URL."), + InvalidVaultUrlFormat("%s0 Initialization failed. Vault URL must start with 'https://'."), // Connection config InvalidConnectionId("%s0 Initialization failed. Invalid connection ID. Specify a valid connection ID."), @@ -66,6 +68,7 @@ public enum ErrorMessage { EmptyKeyInTokens("%s0 Validation error. Invalid key tokens. Specify a valid key."), EmptyValueInTokens("%s0 Validation error. Invalid value in tokens. Specify a valid value."), EmptyUpsert("%s0 Validation error. 'upsert' key can't be empty. Specify an upsert column."), + EmptyUpsertValues("%s0 Validation error. Upsert column values can't be empty. Specify at least one upsert column."), HomogenousNotSupportedWithUpsert("%s0 Validation error. 'homogenous' is not supported with 'upsert'. Specify either 'homogenous' or 'upsert'."), TokensPassedForTokenModeDisable("%s0 Validation error. 'tokenMode' wasn't specified. Set 'tokenMode' to 'ENABLE' to insert tokens."), NoTokensWithTokenMode("%s0 Validation error. Tokens weren't specified for records while 'tokenMode' was %s1. Specify tokens."), @@ -73,11 +76,13 @@ public enum ErrorMessage { InsufficientTokensPassedForTokenModeEnableStrict("%s0 Validation error. 'tokenMode' is set to 'ENABLE_STRICT', but some fields are missing tokens. Specify tokens for all fields."), BatchInsertPartialSuccess("%s0 Insert operation completed with partial success."), BatchInsertFailure("%s0 Insert operation failed."), + RecordSizeExceedError("%s0 Maximum number of records exceeded. The limit is 10000."), // Detokenize InvalidDetokenizeData("%s0 Validation error. Invalid detokenize data. Specify valid detokenize data."), EmptyDetokenizeData("%s0 Validation error. Invalid data tokens. Specify at least one data token."), EmptyTokenInDetokenizeData("%s0 Validation error. Invalid data tokens. Specify a valid data token."), + TokensSizeExceedError("%s0 Maximum number of tokens exceeded. The limit is 10000."), // Get IdsKeyError("%s0 Validation error. 'ids' key is missing from the payload. Specify an 'ids' key."), diff --git a/common/src/main/java/com/skyflow/logs/ErrorLogs.java b/common/src/main/java/com/skyflow/logs/ErrorLogs.java index 8f1156fd..fa7bd5dd 100644 --- a/common/src/main/java/com/skyflow/logs/ErrorLogs.java +++ b/common/src/main/java/com/skyflow/logs/ErrorLogs.java @@ -25,6 +25,8 @@ public enum ErrorLogs { EMPTY_ROLES("Invalid credentials. Roles can not be empty."), EMPTY_OR_NULL_ROLE_IN_ROLES("Invalid credentials. Role can not be null or empty in roles at index %s1."), EMPTY_OR_NULL_CONTEXT("Invalid credentials. Context can not be empty."), + EMPTY_VAULT_URL("Invalid vault config. Vault URL can not be empty."), + INVALID_VAULT_URL_FORMAT("Invalid vault config. Vault URL format is incorrect"), // Bearer token generation INVALID_BEARER_TOKEN("Bearer token is invalid or expired."), @@ -49,9 +51,12 @@ public enum ErrorLogs { EMPTY_TABLE_NAME("Invalid %s1 request. Table name can not be empty."), VALUES_IS_REQUIRED("Invalid %s1 request. Values are required."), EMPTY_VALUES("Invalid %s1 request. Values can not be empty."), + RECORD_SIZE_EXCEED("Maximum number of records exceeded. The limit is 10000."), + TOKENS_SIZE_EXCEED("Maximum number of tokens exceeded. The limit is 10000."), EMPTY_OR_NULL_VALUE_IN_VALUES("Invalid %s1 request. Value can not be null or empty in values for key \"%s2\"."), EMPTY_OR_NULL_KEY_IN_VALUES("Invalid %s1 request. Key can not be null or empty in values"), EMPTY_UPSERT("Invalid %s1 request. Upsert can not be empty."), + EMPTY_UPSERT_VALUES("Invalid %s1 request. Upsert values can not be empty."), HOMOGENOUS_NOT_SUPPORTED_WITH_UPSERT("Invalid %s1 request. Homogenous is not supported when upsert is passed."), TOKENS_NOT_ALLOWED_WITH_TOKEN_MODE_DISABLE("Invalid %s1 request. Tokens are not allowed when tokenMode is DISABLE."), TOKENS_REQUIRED_WITH_TOKEN_MODE("Invalid %s1 request. Tokens are required when tokenMode is %s2."), diff --git a/common/src/main/java/com/skyflow/utils/BaseUtils.java b/common/src/main/java/com/skyflow/utils/BaseUtils.java index b7cf6bb0..a13c9ab5 100644 --- a/common/src/main/java/com/skyflow/utils/BaseUtils.java +++ b/common/src/main/java/com/skyflow/utils/BaseUtils.java @@ -11,6 +11,8 @@ import com.skyflow.serviceaccount.util.BearerToken; import com.skyflow.serviceaccount.util.Token; import com.skyflow.utils.logger.LogUtil; +import io.github.cdimascio.dotenv.Dotenv; +import io.github.cdimascio.dotenv.DotenvException; import org.apache.commons.codec.binary.Base64; import java.io.File; @@ -43,6 +45,7 @@ public static String getVaultURL(String clusterId, Env env, String vaultDomain) return sb.toString(); } + public static String generateBearerToken(Credentials credentials) throws SkyflowException { String bearerToken; if (credentials.getPath() != null) { diff --git a/common/src/main/java/com/skyflow/utils/validations/BaseValidations.java b/common/src/main/java/com/skyflow/utils/validations/BaseValidations.java index 8460ec1d..410b99aa 100644 --- a/common/src/main/java/com/skyflow/utils/validations/BaseValidations.java +++ b/common/src/main/java/com/skyflow/utils/validations/BaseValidations.java @@ -34,7 +34,8 @@ public static void validateVaultConfig(VaultConfig vaultConfig) throws SkyflowEx } else if (clusterId.trim().isEmpty()) { LogUtil.printErrorLog(ErrorLogs.EMPTY_CLUSTER_ID.getLog()); throw new SkyflowException(ErrorCode.INVALID_INPUT.getCode(), ErrorMessage.EmptyClusterId.getMessage()); - } else if (credentials != null) { + } + else if (credentials != null) { validateCredentials(credentials); } } diff --git a/samples/pom.xml b/samples/pom.xml index c48ba302..96f921ee 100644 --- a/samples/pom.xml +++ b/samples/pom.xml @@ -18,7 +18,7 @@ com.skyflow skyflow-java - 1.15.0 + 3.0.0-beta.3 diff --git a/samples/src/main/java/com/example/connection/InvokeConnectionExample.java b/samples/src/main/java/com/example/connection/InvokeConnectionExample.java deleted file mode 100644 index b2e80924..00000000 --- a/samples/src/main/java/com/example/connection/InvokeConnectionExample.java +++ /dev/null @@ -1,101 +0,0 @@ -package com.example.connection; - -import com.skyflow.Skyflow; -import com.skyflow.config.ConnectionConfig; -import com.skyflow.config.Credentials; -import com.skyflow.enums.LogLevel; -import com.skyflow.enums.RequestMethod; -import com.skyflow.errors.SkyflowException; -import com.skyflow.vault.connection.InvokeConnectionRequest; -import com.skyflow.vault.connection.InvokeConnectionResponse; - -import java.util.HashMap; -import java.util.Map; - -/** - * This example demonstrates how to use the Skyflow SDK to invoke API connections. - * It includes: - * 1. Setting up credentials and connection configurations. - * 2. Creating a Skyflow client with multiple connections. - * 3. Sending a POST request with request body and headers. - * 4. Sending a GET request with path and query parameters. - */ -public class InvokeConnectionExample { - public static void main(String[] args) throws SkyflowException { - // Step 1: Set up credentials for API authentication - Credentials credentials = new Credentials(); - credentials.setApiKey(""); // Replace with the actual API key - - // Step 2: Configure the first connection - ConnectionConfig primaryConnectionConfig = new ConnectionConfig(); - primaryConnectionConfig.setConnectionId(""); // Replace with first connection ID - primaryConnectionConfig.setConnectionUrl(""); // Replace with first connection URL - primaryConnectionConfig.setCredentials(credentials); // Assign credentials - - // Step 3: Configure the second connection - ConnectionConfig secondaryConnectionConfig = new ConnectionConfig(); - secondaryConnectionConfig.setConnectionId(""); // Replace with second connection ID - secondaryConnectionConfig.setConnectionUrl(""); // Replace with second connection URL - - // Step 4: Set up credentials for the Skyflow client - Credentials skyflowCredentials = new Credentials(); - skyflowCredentials.setCredentialsString(""); // Replace with the credentials string - - // Step 5: Create a Skyflow client with connection configurations - Skyflow skyflowClient = Skyflow.builder() - .setLogLevel(LogLevel.ERROR) // Set log level to ERROR - .addConnectionConfig(primaryConnectionConfig) // Add the first connection - .addConnectionConfig(secondaryConnectionConfig) // Add the second connection - .addSkyflowCredentials(skyflowCredentials) // Provide Skyflow credentials - .build(); - - // Example 1: Sending a POST request to the first connection - try { - // Set up request body and headers - Map requestBody = new HashMap<>(); - requestBody.put("", ""); // Replace with actual column name and value - requestBody.put("", ""); // Replace with another column name and value - - Map requestHeaders = new HashMap<>(); - requestHeaders.put("", ""); // Replace with actual header name and value - requestHeaders.put("", ""); // Replace with another header name and value - - // Build and send the POST request - InvokeConnectionRequest invokeConnectionRequest1 = InvokeConnectionRequest.builder() - .method(RequestMethod.POST) // HTTP method set to POST - .requestBody(requestBody) // Include request body - .requestHeaders(requestHeaders) // Include request headers - .build(); - - InvokeConnectionResponse invokeConnectionResponse1 = skyflowClient.connection().invoke(invokeConnectionRequest1); - System.out.println("Invoke Connection Response (POST): " + invokeConnectionResponse1); - } catch (SkyflowException e) { - System.out.println("Error while invoking connection (POST):" + e); - } - - // Example 2: Sending a GET request to the second connection - try { - // Set up path and query parameters - Map pathParams = new HashMap<>(); - pathParams.put("", ""); // Replace with actual path parameter - pathParams.put("", ""); // Replace with another path parameter - - Map queryParams = new HashMap<>(); - queryParams.put("", ""); // Replace with actual query parameter - queryParams.put("", ""); // Replace with another query parameter - - // Build and send the GET request - InvokeConnectionRequest invokeConnectionRequest2 = InvokeConnectionRequest.builder() - .method(RequestMethod.GET) // HTTP method set to GET - .pathParams(pathParams) // Include path parameters - .queryParams(queryParams) // Include query parameters - .build(); - - InvokeConnectionResponse invokeConnectionResponse2 = skyflowClient - .connection("").invoke(invokeConnectionRequest2); - System.out.println("Invoke Connection Response (GET): " + invokeConnectionResponse2); - } catch (SkyflowException e) { - System.out.println("Error while invoking connection (GET):" + e); - } - } -} diff --git a/samples/src/main/java/com/example/detect/DeidentifyFileExample.java b/samples/src/main/java/com/example/detect/DeidentifyFileExample.java deleted file mode 100644 index 7f573d33..00000000 --- a/samples/src/main/java/com/example/detect/DeidentifyFileExample.java +++ /dev/null @@ -1,114 +0,0 @@ -package com.example.detect; - -import java.io.File; - -import com.skyflow.Skyflow; -import com.skyflow.config.Credentials; -import com.skyflow.config.VaultConfig; -import com.skyflow.enums.Env; -import com.skyflow.enums.LogLevel; -import com.skyflow.enums.MaskingMethod; -import com.skyflow.errors.SkyflowException; -import com.skyflow.vault.detect.DeidentifyFileRequest; -import com.skyflow.vault.detect.DeidentifyFileResponse; -import com.skyflow.vault.detect.FileInput; - -/** - * Skyflow Deidentify File Example - *

- * This example demonstrates how to use the Skyflow SDK to deidentify file - * It has all available options for deidentifying files. - * Supported file types: images (jpg, png, etc.), pdf, audio (mp3, wav), documents, spreadsheets, presentations, structured text. - * It includes: - * 1. Configure credentials - * 2. Set up vault configuration - * 3. Create a deidentify file request with all options - * 4. Call deidentifyFile to deidentify file. - * 5. Handle response and errors - */ -public class DeidentifyFileExample { - - public static void main(String[] args) throws SkyflowException { - // Step 1: Set up credentials for the first vault configuration - Credentials credentials = new Credentials(); - credentials.setPath(""); // Replace with the path to the credentials file - - // Step 2: Configure the vault config - VaultConfig vaultConfig = new VaultConfig(); - vaultConfig.setVaultId(""); // Replace with the ID of the vault - vaultConfig.setClusterId(""); // Replace with the cluster ID of the vault - vaultConfig.setEnv(Env.PROD); // Set the environment (e.g., DEV, STAGE, PROD) - vaultConfig.setCredentials(credentials); // Associate the credentials with the vault - - // Step 3: Create a Skyflow client - Skyflow skyflowClient = Skyflow.builder() - .setLogLevel(LogLevel.DEBUG) // Enable debugging for detailed logs - .addVaultConfig(vaultConfig) // Add the vault configuration - .build(); - - try { - - // Step 4: Create a deidentify file request with all options - - // Create file object - File file = new File("") // Alternatively, you can use .filePath() - .build(); - - // Output configuration - String outputDirectory = ""; // Replace with the desired output directory to save the deidentified file - - // Entities to detect - // List detectEntities = new ArrayList<>(); - // detectEntities.add(DetectEntities.IP_ADDRESS); // Replace with the entities you want to detect - - // Image-specific options - // Boolean outputProcessedImage = true; // Include processed image in output - // Boolean outputOcrText = true; // Include OCR text in output - MaskingMethod maskingMethod = MaskingMethod.BLACKBOX; // Masking method for images - - // PDF-specific options - // Integer pixelDensity = 15; // Pixel density for PDF processing - // Integer maxResolution = 2000; // Max resolution for PDF - - // Audio-specific options - // Boolean outputProcessedAudio = true; // Include processed audio - // DetectOutputTranscriptions outputTanscription = DetectOutputTranscriptions.PLAINTEXT_TRANSCRIPTION; // Transcription type - - // Audio bleep configuration - // AudioBleep audioBleep = AudioBleep.builder() - // .frequency(5D) // Pitch in Hz - // .startPadding(7D) // Padding at start (seconds) - // .stopPadding(8D) // Padding at end (seconds) - // .build(); - - Integer waitTime = 20; // Max wait time for response (max 64 seconds) - - DeidentifyFileRequest deidentifyFileRequest = DeidentifyFileRequest.builder() - .file(fileInput) - .waitTime(waitTime) - // .entities(detectEntities) - .outputDirectory(outputDirectory) - .maskingMethod(maskingMethod) - // .outputProcessedImage(outputProcessedImage) - // .outputOcrText(outputOcrText) - // .pixelDensity(pixelDensity) - // .maxResolution(maxResolution) - // .outputProcessedAudio(outputProcessedAudio) - // .outputTranscription(outputTanscription) - // .bleep(audioBleep) - .build(); - - - DeidentifyFileResponse deidentifyFileResponse = skyflowClient.detect(vaultConfig.getVaultId()).deidentifyFile(deidentifyFileRequest); - System.out.println("Deidentify file response: " + deidentifyFileResponse.toString()); - } catch (SkyflowException e) { - System.err.println("Error occurred during deidentify file: "); - e.printStackTrace(); - } - } -} \ No newline at end of file diff --git a/samples/src/main/java/com/example/detect/DeidentifyTextExample.java b/samples/src/main/java/com/example/detect/DeidentifyTextExample.java deleted file mode 100644 index 837dde00..00000000 --- a/samples/src/main/java/com/example/detect/DeidentifyTextExample.java +++ /dev/null @@ -1,142 +0,0 @@ -package com.example.detect; - -import java.util.ArrayList; -import java.util.List; - -import com.skyflow.Skyflow; -import com.skyflow.config.Credentials; -import com.skyflow.config.VaultConfig; -import com.skyflow.enums.DetectEntities; -import com.skyflow.enums.Env; -import com.skyflow.enums.LogLevel; -import com.skyflow.errors.SkyflowException; -import com.skyflow.vault.detect.DeidentifyTextRequest; -import com.skyflow.vault.detect.DeidentifyTextResponse; -import com.skyflow.vault.detect.TokenFormat; - -/** - * Skyflow Deidentify Text Example - *

- * This example demonstrates how to use the Skyflow SDK to deidentify text data - * across multiple vaults. It includes: - * 1. Setting up credentials and vault configurations. - * 2. Creating a Skyflow client with multiple vaults. - * 3. Performing deidentify of text with various options. - * 4. Handling responses and errors. - */ - -public class DeidentifyTextExample { - public static void main(String[] args) throws SkyflowException { - - // Step 1: Set up credentials for the first vault configuration - Credentials credentials = new Credentials(); - credentials.setPath(""); // Replace with the path to the credentials file - - // Step 2: Configure the first vault (Blitz) - VaultConfig blitzConfig = new VaultConfig(); - blitzConfig.setVaultId(""); // Replace with the ID of the first vault - blitzConfig.setClusterId(""); // Replace with the cluster ID of the first vault - blitzConfig.setEnv(Env.DEV); // Set the environment (e.g., DEV, STAGE, PROD) - blitzConfig.setCredentials(credentials); // Associate the credentials with the vault - - // Step 3: Configure the second vault (Stage) - VaultConfig stageConfig = new VaultConfig(); - stageConfig.setVaultId(""); // Replace with the ID of the second vault - stageConfig.setClusterId(""); // Replace with the cluster ID of the second vault - stageConfig.setEnv(Env.STAGE); // Set the environment for the second vault - - // Step 4: Set up credentials for the Skyflow client - Credentials skyflowCredentials = new Credentials(); - skyflowCredentials.setPath(""); // Replace with the path to another credentials file - - // Step 5: Create a Skyflow client and add vault configurations - Skyflow skyflowClient = Skyflow.builder() - .setLogLevel(LogLevel.DEBUG) // Enable debugging for detailed logs - .addVaultConfig(blitzConfig) // Add the first vault configuration - .addVaultConfig(stageConfig) // Add the second vault configuration - .addSkyflowCredentials(skyflowCredentials) // Add general Skyflow credentials - .build(); - - // Step 6: Configuring the different options for deidentify - // Replace with the entity you want to detect - List detectEntitiesList = new ArrayList<>(); - detectEntitiesList.add(DetectEntities.SSN); - detectEntitiesList.add(DetectEntities.CREDIT_CARD); - - // Replace with the entity you want to detect with vault token - List vaultTokenList = new ArrayList<>(); - vaultTokenList.add(DetectEntities.SSN); - vaultTokenList.add(DetectEntities.CREDIT_CARD); - - // Replace with the entity you want to detect with entity only - // List entityOnlyList = new ArrayList<>(); - // entityOnlyList.add(DetectEntities.SSN); - - // Replace with the entity you want to detect with entity unique counter - // List entityUniqueCounterList = new ArrayList<>(); - // entityUniqueCounterList.add(DetectEntities.SSN); - - // Replace with the regex patterns you want to allow during deidentification - // List allowRegexList = new ArrayList<>(); - // allowRegexList.add(""); - - // Replace with the regex patterns you want to restrict during deidentification - // List restrictRegexList = new ArrayList<>(); - // restrictRegexList.add("YOUR_RESTRICT_REGEX_LIST"); - - // Configure Token Format - TokenFormat tokenFormat = TokenFormat.builder() - .vaultToken(vaultTokenList) - // .entityOnly(entityOnlyList) - // .entityUniqueCounter(entityUniqueCounterList) - .build(); - - // Configure Transformation for deidentified entities - // List detectEntitiesTransformationList = new ArrayList<>(); - // detectEntitiesTransformationList.add(DetectEntities.DOB); // Replace with the entity you want to transform - // detectEntitiesTransformationList.add(DetectEntities.DATE); - - // DateTransformation dateTransformation = new DateTransformation(20, 5, detectEntitiesTransformationList); - // Transformations transformations = new Transformations(dateTransformation); - - // Example 1: Deidentify text on the first vault - try { - // Create a deidentify text request for the first vault - DeidentifyTextRequest deidentifyTextRequest = DeidentifyTextRequest.builder() - .text("My SSN is 123-45-6789 and my card is 4111 1111 1111 1111.") // Replace with the text you want to deidentify - .entities(detectEntitiesList) - // .allowRegexList(allowRegexList) - // .restrictRegexList(restrictRegexList) - .tokenFormat(tokenFormat) - // .transformations(transformations) - .build(); - - - DeidentifyTextResponse deidentifyTextResponse = skyflowClient.detect(blitzConfig.getVaultId()).deidentifyText(deidentifyTextRequest); - - System.out.println("Deidentify text Response (Vault1): " + deidentifyTextResponse); - } catch (SkyflowException e) { - System.err.println("Error occurred during deidentify (Vault1): "); - e.printStackTrace(); - } - // Example 2: Deidentify text on the second vault - try { - // Create a deidentify text request for the second vault - DeidentifyTextRequest deidentifyTextRequest2 = DeidentifyTextRequest.builder() - .text("My SSN is 123-45-6789 and my card is 4111 1111 1111 1111.") // Replace with the text you want to deidentify - .entities(detectEntitiesList) - // .allowRegexList(allowRegexList) - // .restrictRegexList(restrictRegexList) - .tokenFormat(tokenFormat) - // .transformations(transformations) - .build(); - - DeidentifyTextResponse deidentifyTextResponse2 = skyflowClient.detect(stageConfig.getVaultId()).deidentifyText(deidentifyTextRequest2); - System.out.println("Deidentify text Response (Vault2): " + deidentifyTextResponse2); - - } catch (SkyflowException e) { - System.err.println("Error occurred during deidentify (Vault2): "); - e.printStackTrace(); - } - } -} \ No newline at end of file diff --git a/samples/src/main/java/com/example/detect/GetDetectRunExample.java b/samples/src/main/java/com/example/detect/GetDetectRunExample.java deleted file mode 100644 index 09fc2bc4..00000000 --- a/samples/src/main/java/com/example/detect/GetDetectRunExample.java +++ /dev/null @@ -1,55 +0,0 @@ -package com.example.detect; - -import com.skyflow.Skyflow; -import com.skyflow.config.Credentials; -import com.skyflow.config.VaultConfig; -import com.skyflow.enums.Env; -import com.skyflow.enums.LogLevel; -import com.skyflow.errors.SkyflowException; -import com.skyflow.vault.detect.DeidentifyFileResponse; -import com.skyflow.vault.detect.GetDetectRunRequest; - -/** - * Skyflow Get Detect Run Example - *

- * This example demonstrates how to: - * 1. Configure credentials - * 2. Set up vault configuration - * 3. Create a get detect run request - * 4. Call getDetectRun to poll for file processing results - * 5. Handle response and errors - */ -public class GetDetectRunExample { - public static void main(String[] args) throws SkyflowException { - // Step 1: Configure credentials - Credentials credentials = new Credentials(); - credentials.setPath(""); // Replace with the path to the credentials file - - // Step 2: Configure the vault config - VaultConfig vaultConfig = new VaultConfig(); - vaultConfig.setVaultId(""); // Replace with the ID of the vault - vaultConfig.setClusterId(""); // Replace with the cluster ID of the vault - vaultConfig.setEnv(Env.PROD); // Set the environment (e.g., DEV, STAGE, PROD) - vaultConfig.setCredentials(credentials); // Associate the credentials with the vault - - // Step 3: Create a Skyflow client - Skyflow skyflowClient = Skyflow.builder() - .setLogLevel(LogLevel.DEBUG) // Enable debugging for detailed logs - .addVaultConfig(vaultConfig) // Add the vault configuration - .build(); - - try { - // Step 4: Create a get detect run request - GetDetectRunRequest getDetectRunRequest = GetDetectRunRequest.builder() - .runId("") // Replace with the runId from deidentifyFile call - .build(); - - // Step 5: Call getDetectRun to poll for file processing results - DeidentifyFileResponse deidentifyFileResponse = skyflowClient.detect(vaultConfig.getVaultId()).getDetectRun(getDetectRunRequest); - System.out.println("Get Detect Run Response: " + deidentifyFileResponse); - } catch (SkyflowException e) { - System.err.println("Error occurred during get detect run: "); - e.printStackTrace(); - } - } -} \ No newline at end of file diff --git a/samples/src/main/java/com/example/serviceaccount/BearerTokenExpiryExample.java b/samples/src/main/java/com/example/serviceaccount/BearerTokenExpiryExample.java deleted file mode 100644 index 1f56296d..00000000 --- a/samples/src/main/java/com/example/serviceaccount/BearerTokenExpiryExample.java +++ /dev/null @@ -1,86 +0,0 @@ -package com.example.serviceaccount; - -import com.skyflow.Skyflow; -import com.skyflow.config.Credentials; -import com.skyflow.config.VaultConfig; -import com.skyflow.enums.Env; -import com.skyflow.enums.LogLevel; -import com.skyflow.enums.RedactionType; -import com.skyflow.errors.SkyflowException; -import com.skyflow.vault.tokens.DetokenizeRequest; -import com.skyflow.vault.tokens.DetokenizeResponse; -import io.github.cdimascio.dotenv.Dotenv; -import java.util.ArrayList; - -/** - * This example demonstrates how to configure and use the Skyflow SDK - * to detokenize sensitive data stored in a Skyflow vault. - * It includes setting up credentials, configuring the vault, and - * making a detokenization request. The code also implements a retry - * mechanism to handle unauthorized access errors (HTTP 401). - */ -public class BearerTokenExpiryExample { - public static void main(String[] args) { - try { - // Setting up credentials for accessing the Skyflow vault - Credentials vaultCredentials = new Credentials(); - vaultCredentials.setCredentialsString(""); - - // Configuring the Skyflow vault with necessary details - VaultConfig vaultConfig = new VaultConfig(); - vaultConfig.setVaultId(""); // Vault ID - vaultConfig.setClusterId(""); // Cluster ID - vaultConfig.setEnv(Env.PROD); // Environment (e.g., DEV, PROD) - vaultConfig.setCredentials(vaultCredentials); // Setting credentials - - // Creating a Skyflow client instance with the configured vault - Skyflow skyflowClient = Skyflow.builder() - .setLogLevel(LogLevel.ERROR) // Setting log level to ERROR - .addVaultConfig(vaultConfig) // Adding vault configuration - .build(); - - // Attempting to detokenize data using the Skyflow client - try { - detokenizeData(skyflowClient); - } catch (SkyflowException e) { - // Retry detokenization if the error is due to unauthorized access (HTTP 401) - if (e.getHttpCode() == 401) { - detokenizeData(skyflowClient); - } else { - // Rethrow the exception for other error codes - throw e; - } - } - } catch (SkyflowException e) { - // Handling any exceptions that occur during the process - System.out.println("An error occurred: " + e.getMessage()); - } - } - - /** - * Method to detokenize data using the Skyflow client. - * It sends a detokenization request with a list of tokens and prints the response. - * - * @param skyflowClient The Skyflow client instance used for detokenization. - * @throws SkyflowException If an error occurs during the detokenization process. - */ - public static void detokenizeData(Skyflow skyflowClient) throws SkyflowException { - // Creating a list of tokens to be detokenized - ArrayList tokenList = new ArrayList<>(); - tokenList.add(""); // First token - tokenList.add(""); // Second token - - // Building a detokenization request with the token list and configuration - DetokenizeRequest detokenizeRequest = DetokenizeRequest.builder() - .tokens(tokenList) // Adding tokens to the request - .continueOnError(false) // Stop on error - .redactionType(RedactionType.PLAIN_TEXT) // Redaction type (e.g., PLAIN_TEXT) - .build(); - - // Sending the detokenization request and receiving the response - DetokenizeResponse detokenizeResponse = skyflowClient.vault().detokenize(detokenizeRequest); - - // Printing the detokenized response - System.out.println(detokenizeResponse); - } -} diff --git a/samples/src/main/java/com/example/serviceaccount/BearerTokenGenerationExample.java b/samples/src/main/java/com/example/serviceaccount/BearerTokenGenerationExample.java deleted file mode 100644 index c4578545..00000000 --- a/samples/src/main/java/com/example/serviceaccount/BearerTokenGenerationExample.java +++ /dev/null @@ -1,66 +0,0 @@ -package com.example.serviceaccount; - -import com.skyflow.errors.SkyflowException; -import com.skyflow.serviceaccount.util.BearerToken; -import com.skyflow.serviceaccount.util.Token; - -import java.io.File; - -/** - * Example program to generate a Bearer Token using Skyflow's BearerToken utility. - * The token can be generated in two ways: - * 1. Using the file path to a credentials.json file. - * 2. Using the JSON content of the credentials file as a string. - */ -public class BearerTokenGenerationExample { - public static void main(String[] args) { - // Variable to store the generated token - String token = null; - - // Example 1: Generate Bearer Token using a credentials.json file - try { - // Specify the full file path to the credentials.json file - String filePath = ""; - - // Check if the token is either not initialized or has expired - if (Token.isExpired(token)) { - // Create a BearerToken object using the credentials file - BearerToken bearerToken = BearerToken.builder() - .setCredentials(new File(filePath)) // Set credentials from the file path - .build(); - - // Generate a new Bearer Token - token = bearerToken.getBearerToken(); - } - - // Print the generated Bearer Token to the console - System.out.println("Generated Bearer Token (from file): " + token); - } catch (SkyflowException e) { - // Handle any exceptions encountered during the token generation process - e.printStackTrace(); - } - - // Example 2: Generate Bearer Token using the credentials JSON as a string - try { - // Provide the credentials JSON content as a string - String fileContents = ""; - - // Check if the token is either not initialized or has expired - if (Token.isExpired(token)) { - // Create a BearerToken object using the credentials string - BearerToken bearerToken = BearerToken.builder() - .setCredentials(fileContents) // Set credentials from the string - .build(); - - // Generate a new Bearer Token - token = bearerToken.getBearerToken(); - } - - // Print the generated Bearer Token to the console - System.out.println("Generated Bearer Token (from string): " + token); - } catch (SkyflowException e) { - // Handle any exceptions encountered during the token generation process - e.printStackTrace(); - } - } -} diff --git a/samples/src/main/java/com/example/serviceaccount/BearerTokenGenerationUsingThreadsExample.java b/samples/src/main/java/com/example/serviceaccount/BearerTokenGenerationUsingThreadsExample.java deleted file mode 100644 index 30d8f9ba..00000000 --- a/samples/src/main/java/com/example/serviceaccount/BearerTokenGenerationUsingThreadsExample.java +++ /dev/null @@ -1,72 +0,0 @@ -package com.example.serviceaccount; - -import com.skyflow.errors.SkyflowException; -import com.skyflow.serviceaccount.util.BearerToken; - -import java.io.File; - -/** - * This example demonstrates how to generate Bearer tokens in two different ways: - * 1. Using a credentials file specified by its file path. - * 2. Using the credentials as a string. - *

- * The code also showcases multithreaded token generation with a shared context (`ctx`), - * where each thread generates and prints tokens repeatedly. - */ -public class BearerTokenGenerationUsingThreadsExample { - public static void main(String[] args) { - // Example 1: Generate Bearer token using a credentials file path - try { - // Step 1: Specify the path to the credentials file - String filePath = ""; // Replace with the actual file path - - // Step 2: Create a BearerToken object using the file path - final BearerToken bearerToken = BearerToken.builder() - .setCredentials(new File(filePath)) // Provide the credentials file - .setCtx("abc") // Specify a context string ("abc" in this case) - .build(); - - // Step 3: Create and start a thread to repeatedly generate and print tokens - Thread t = new Thread(() -> { - for (int i = 0; i < 5; i++) { // Loop to generate tokens 5 times - try { - System.out.println(bearerToken.getBearerToken()); // Print the Bearer token - } catch (SkyflowException e) { // Handle exceptions during token generation - Thread.currentThread().interrupt(); // Interrupt the thread on error - throw new RuntimeException(e); // Wrap and propagate the exception - } - } - }); - t.start(); // Start the thread - } catch (Exception e) { // Handle exceptions during BearerToken creation - e.printStackTrace(); - } - - // Example 2: Generate Bearer token using credentials as a string - try { - // Step 1: Specify the credentials as a string (file contents) - String fileContents = ""; // Replace with actual file contents - - // Step 2: Create a BearerToken object using the credentials string - final BearerToken bearerToken = BearerToken.builder() - .setCredentials(fileContents) // Provide the credentials as a string - .setCtx("abc") // Specify a context string ("abc" in this case) - .build(); - - // Step 3: Create and start a thread to repeatedly generate and print tokens - Thread t = new Thread(() -> { - for (int i = 0; i < 5; i++) { // Loop to generate tokens 5 times - try { - System.out.println(bearerToken.getBearerToken()); // Print the Bearer token - } catch (SkyflowException e) { // Handle exceptions during token generation - Thread.currentThread().interrupt(); // Interrupt the thread on error - throw new RuntimeException(e); // Wrap and propagate the exception - } - } - }); - t.start(); // Start the thread - } catch (Exception e) { // Handle exceptions during BearerToken creation - e.printStackTrace(); - } - } -} diff --git a/samples/src/main/java/com/example/serviceaccount/BearerTokenGenerationWithContextExample.java b/samples/src/main/java/com/example/serviceaccount/BearerTokenGenerationWithContextExample.java deleted file mode 100644 index 3ed9e267..00000000 --- a/samples/src/main/java/com/example/serviceaccount/BearerTokenGenerationWithContextExample.java +++ /dev/null @@ -1,61 +0,0 @@ -package com.example.serviceaccount; - -import com.skyflow.errors.SkyflowException; -import com.skyflow.serviceaccount.util.BearerToken; - -import java.io.File; - -/** - * Example program to generate a Bearer Token using Skyflow's BearerToken utility. - * The token is generated using two approaches: - * 1. By providing the credentials.json file path. - * 2. By providing the contents of credentials.json as a string. - */ -public class BearerTokenGenerationWithContextExample { - public static void main(String[] args) { - // Variable to store the generated Bearer Token - String bearerToken = null; - - // Approach 1: Generate Bearer Token by specifying the path to the credentials.json file - try { - // Replace with the full path to your credentials.json file - String filePath = ""; - - // Create a BearerToken object using the file path - BearerToken token = BearerToken.builder() - .setCredentials(new File(filePath)) // Set credentials using a File object - .setCtx("abc") // Set context string (example: "abc") - .build(); // Build the BearerToken object - - // Retrieve the Bearer Token as a string - bearerToken = token.getBearerToken(); - - // Print the generated Bearer Token to the console - System.out.println(bearerToken); - } catch (SkyflowException e) { - // Handle exceptions specific to Skyflow operations - e.printStackTrace(); - } - - // Approach 2: Generate Bearer Token by specifying the contents of credentials.json as a string - try { - // Replace with the actual contents of your credentials.json file - String fileContents = ""; - - // Create a BearerToken object using the file contents as a string - BearerToken token = BearerToken.builder() - .setCredentials(fileContents) // Set credentials using a string representation of the file - .setCtx("abc") // Set context string (example: "abc") - .build(); // Build the BearerToken object - - // Retrieve the Bearer Token as a string - bearerToken = token.getBearerToken(); - - // Print the generated Bearer Token to the console - System.out.println(bearerToken); - } catch (SkyflowException e) { - // Handle exceptions specific to Skyflow operations - e.printStackTrace(); - } - } -} diff --git a/samples/src/main/java/com/example/serviceaccount/ScopedTokenGenerationExample.java b/samples/src/main/java/com/example/serviceaccount/ScopedTokenGenerationExample.java deleted file mode 100644 index 3cba8bd5..00000000 --- a/samples/src/main/java/com/example/serviceaccount/ScopedTokenGenerationExample.java +++ /dev/null @@ -1,66 +0,0 @@ -package com.example.serviceaccount; - -import com.skyflow.errors.SkyflowException; -import com.skyflow.serviceaccount.util.BearerToken; - -import java.io.File; -import java.util.ArrayList; - -/** - * This example demonstrates how to generate a Scoped Bearer Token in two ways: - * 1. Using a credentials file specified by its file path. - * 2. Using the credentials as a string. - *

- * Scoped tokens are generated by assigning specific roles for access control. - */ -public class ScopedTokenGenerationExample { - public static void main(String[] args) { - String scopedToken = null; // Variable to store the generated Scoped Bearer Token - - // Example 1: Generate Scoped Token using a credentials file path - try { - // Step 1: Specify the roles required for the scoped token - ArrayList roles = new ArrayList<>(); - roles.add("YOUR_ROLE_ID"); // Replace with your actual role ID - - // Step 2: Specify the path to the credentials file - String filePath = ""; // Replace with the actual file path - - // Step 3: Create a BearerToken object using the file path and roles - BearerToken bearerToken = BearerToken.builder() - .setCredentials(new File(filePath)) // Provide the credentials file - .setRoles(roles) // Set the roles for the scoped token - .build(); - - // Step 4: Generate and print the Scoped Bearer Token - scopedToken = bearerToken.getBearerToken(); - System.out.println("Scoped Token (using file path): " + scopedToken); - } catch (SkyflowException e) { // Handle exceptions during token generation - System.out.println("Error occurred while generating Scoped Token using file path:"); - e.printStackTrace(); - } - - // Example 2: Generate Scoped Token using credentials as a string - try { - // Step 1: Specify the roles required for the scoped token - ArrayList roles = new ArrayList<>(); - roles.add("YOUR_ROLE_ID"); // Replace with your actual role ID - - // Step 2: Specify the credentials as a string (file contents) - String fileContents = ""; // Replace with actual file contents - - // Step 3: Create a BearerToken object using the credentials string and roles - BearerToken bearerToken = BearerToken.builder() - .setCredentials(fileContents) // Provide the credentials as a string - .setRoles(roles) // Set the roles for the scoped token - .build(); - - // Step 4: Generate and print the Scoped Bearer Token - scopedToken = bearerToken.getBearerToken(); - System.out.println("Scoped Token (using credentials string): " + scopedToken); - } catch (SkyflowException e) { // Handle exceptions during token generation - System.out.println("Error occurred while generating Scoped Token using credentials string:"); - e.printStackTrace(); - } - } -} diff --git a/samples/src/main/java/com/example/serviceaccount/SignedTokenGenerationExample.java b/samples/src/main/java/com/example/serviceaccount/SignedTokenGenerationExample.java deleted file mode 100644 index 98f552f3..00000000 --- a/samples/src/main/java/com/example/serviceaccount/SignedTokenGenerationExample.java +++ /dev/null @@ -1,74 +0,0 @@ -package com.example.serviceaccount; - -import com.skyflow.errors.SkyflowException; -import com.skyflow.serviceaccount.util.SignedDataTokenResponse; -import com.skyflow.serviceaccount.util.SignedDataTokens; - -import java.io.File; -import java.util.ArrayList; -import java.util.List; - -/** - * This example demonstrates how to generate Signed Data Tokens using two methods: - * 1. Specifying the path to a credentials JSON file. - * 2. Providing the credentials JSON as a string. - *

- * Signed data tokens are used to verify and securely transmit data with a specified context and TTL. - */ -public class SignedTokenGenerationExample { - public static void main(String[] args) { - List signedTokenValues; // List to store signed data token responses - - // Example 1: Generate Signed Data Token using a credentials file path - try { - // Step 1: Specify the path to the service account credentials JSON file - String filePath = ""; // Replace with the actual file path - - // Step 2: Set the context and create the list of data tokens to be signed - String context = "abc"; // Replace with your specific context (e.g., session identifier) - ArrayList dataTokens = new ArrayList<>(); - dataTokens.add("YOUR_DATA_TOKEN_1"); // Replace with your actual data token(s) - - // Step 3: Build the SignedDataTokens object - SignedDataTokens signedToken = SignedDataTokens.builder() - .setCredentials(new File(filePath)) // Provide the credentials file - .setCtx(context) // Set the context for the token - .setTimeToLive(30) // Set the TTL (in seconds) - .setDataTokens(dataTokens) // Set the data tokens to sign - .build(); - - // Step 4: Retrieve and print the signed data tokens - signedTokenValues = signedToken.getSignedDataTokens(); - System.out.println("Signed Tokens (using file path): " + signedTokenValues); - } catch (SkyflowException e) { - System.out.println("Error occurred while generating signed tokens using file path:"); - e.printStackTrace(); - } - - // Example 2: Generate Signed Data Token using credentials JSON as a string - try { - // Step 1: Provide the contents of the credentials JSON file as a string - String fileContents = ""; // Replace with actual JSON content - - // Step 2: Set the context and create the list of data tokens to be signed - String context = "abc"; // Replace with your specific context - ArrayList dataTokens = new ArrayList<>(); - dataTokens.add("YOUR_DATA_TOKEN_1"); // Replace with your actual data token(s) - - // Step 3: Build the SignedDataTokens object - SignedDataTokens signedToken = SignedDataTokens.builder() - .setCredentials(fileContents) // Provide the credentials as a string - .setCtx(context) // Set the context for the token - .setTimeToLive(30) // Set the TTL (in seconds) - .setDataTokens(dataTokens) // Set the data tokens to sign - .build(); - - // Step 4: Retrieve and print the signed data tokens - signedTokenValues = signedToken.getSignedDataTokens(); - System.out.println("Signed Tokens (using credentials string): " + signedTokenValues); - } catch (SkyflowException e) { - System.out.println("Error occurred while generating signed tokens using credentials string:"); - e.printStackTrace(); - } - } -} diff --git a/samples/src/main/java/com/example/vault/BulkDetokenizeAsync.java b/samples/src/main/java/com/example/vault/BulkDetokenizeAsync.java new file mode 100644 index 00000000..9673ab81 --- /dev/null +++ b/samples/src/main/java/com/example/vault/BulkDetokenizeAsync.java @@ -0,0 +1,81 @@ +package com.example.vault; + +import com.skyflow.Skyflow; +import com.skyflow.config.Credentials; +import com.skyflow.config.VaultConfig; +import com.skyflow.enums.Env; +import com.skyflow.enums.LogLevel; +import com.skyflow.errors.SkyflowException; +import com.skyflow.vault.data.DetokenizeRequest; +import com.skyflow.vault.data.DetokenizeResponse; +import com.skyflow.vault.data.TokenGroupRedactions; + +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.CompletionException; + +/** + * This sample demonstrates how to perform an asynchronous bulk detokenize operation using the Skyflow Java SDK. + * The process involves: + * 1. Setting up credentials and vault configuration + * 2. Creating a list of tokens to detokenize + * 3. Configuring token group redactions + * 4. Building and executing an async bulk detokenize request + * 5. Handling the detokenize response or errors using CompletableFuture + */ +public class BulkDetokenizeAsync { + + public static void main(String[] args) { + try { + // Step 1: Initialize credentials using credentials string + String credentialsString = ""; + Credentials credentials = new Credentials(); + credentials.setCredentialsString(credentialsString); + + // Step 2: Configure the vault with required parameters + VaultConfig vaultConfig = new VaultConfig(); + vaultConfig.setVaultId(""); + vaultConfig.setClusterId(""); + vaultConfig.setEnv(Env.PROD); + vaultConfig.setCredentials(credentials); + + // Step 3: Create Skyflow client instance with error logging + Skyflow skyflowClient = Skyflow.builder() + .setLogLevel(LogLevel.ERROR) + .addVaultConfig(vaultConfig) + .build(); + + // Step 4: Prepare list of tokens to detokenize + ArrayList tokens = new ArrayList<>(); + tokens.add(""); + tokens.add(""); + + // Step 5: Configure token group redactions + TokenGroupRedactions tokenGroupRedaction = TokenGroupRedactions.builder() + .tokenGroupName("") + .redaction("") + .build(); + List tokenGroupRedactions = new ArrayList<>(); + tokenGroupRedactions.add(tokenGroupRedaction); + + // Step 6: Build the detokenize request + DetokenizeRequest detokenizeRequest = DetokenizeRequest.builder() + .tokens(tokens) + .tokenGroupRedactions(tokenGroupRedactions) + .build(); + + // Step 7: Execute the async bulk detokenize operation and handle response using callbacks + CompletableFuture future = skyflowClient.vault().bulkDetokenizeAsync(detokenizeRequest); + future.thenAccept(response -> { + System.out.println("Async bulk detokenize resolved with response:\t" + response); + }).exceptionally(throwable -> { + System.err.println("Async bulk detokenize rejected with error:\t" + throwable.getMessage()); + throw new CompletionException(throwable); + }); + } catch (SkyflowException e) { + // Step 8: Handle any synchronous errors that occur during setup + System.err.println("Error in Skyflow operations: " + e.getMessage()); + } + } +} \ No newline at end of file diff --git a/samples/src/main/java/com/example/vault/BulkDetokenizeSync.java b/samples/src/main/java/com/example/vault/BulkDetokenizeSync.java new file mode 100644 index 00000000..dbd3dee4 --- /dev/null +++ b/samples/src/main/java/com/example/vault/BulkDetokenizeSync.java @@ -0,0 +1,74 @@ +package com.example.vault; + +import com.skyflow.Skyflow; +import com.skyflow.config.Credentials; +import com.skyflow.config.VaultConfig; +import com.skyflow.enums.Env; +import com.skyflow.enums.LogLevel; +import com.skyflow.errors.SkyflowException; +import com.skyflow.vault.data.DetokenizeRequest; +import com.skyflow.vault.data.DetokenizeResponse; +import com.skyflow.vault.data.TokenGroupRedactions; + +import java.util.ArrayList; +import java.util.List; + +/** + * This sample demonstrates how to perform a synchronous bulk detokenize operation using the Skyflow Java SDK. + * The process involves: + * 1. Setting up credentials and vault configuration + * 2. Creating a list of tokens to detokenize + * 3. Configuring token group redactions + * 4. Building and executing a bulk detokenize request + * 5. Handling the detokenize response or any potential errors + */ +public class BulkDetokenizeSync { + + public static void main(String[] args) { + try { + // Step 1: Initialize credentials using credentials string + String credentialsString = ""; + Credentials credentials = new Credentials(); + credentials.setCredentialsString(credentialsString); + + // Step 2: Configure the vault with required parameters + VaultConfig vaultConfig = new VaultConfig(); + vaultConfig.setVaultId(""); + vaultConfig.setClusterId(""); + vaultConfig.setEnv(Env.PROD); + vaultConfig.setCredentials(credentials); + + // Step 3: Create Skyflow client instance with error logging + Skyflow skyflowClient = Skyflow.builder() + .setLogLevel(LogLevel.ERROR) + .addVaultConfig(vaultConfig) + .build(); + + // Step 4: Prepare list of tokens to detokenize + ArrayList tokens = new ArrayList<>(); + tokens.add(""); + tokens.add(""); + + // Step 5: Configure token group redactions + TokenGroupRedactions tokenGroupRedaction = TokenGroupRedactions.builder() + .tokenGroupName("") + .redaction("") + .build(); + List tokenGroupRedactions = new ArrayList<>(); + tokenGroupRedactions.add(tokenGroupRedaction); + + // Step 6: Build the detokenize request + DetokenizeRequest detokenizeRequest = DetokenizeRequest.builder() + .tokens(tokens) + .tokenGroupRedactions(tokenGroupRedactions) + .build(); + + // Step 7: Execute the bulk detokenize operation and print the response + DetokenizeResponse detokenizeResponse = skyflowClient.vault().bulkDetokenize(detokenizeRequest); + System.out.println(detokenizeResponse); + } catch (SkyflowException e) { + // Step 8: Handle any errors that occur during the process + System.err.println("Error in Skyflow operations: " + e.getMessage()); + } + } +} \ No newline at end of file diff --git a/samples/src/main/java/com/example/vault/BulkInsertAsync.java b/samples/src/main/java/com/example/vault/BulkInsertAsync.java new file mode 100644 index 00000000..30e675c7 --- /dev/null +++ b/samples/src/main/java/com/example/vault/BulkInsertAsync.java @@ -0,0 +1,81 @@ +package com.example.vault; + +import com.skyflow.Skyflow; +import com.skyflow.config.Credentials; +import com.skyflow.config.VaultConfig; +import com.skyflow.enums.Env; +import com.skyflow.enums.LogLevel; +import com.skyflow.vault.data.InsertRequest; +import com.skyflow.vault.data.InsertResponse; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.CompletionException; + +/** + * This sample demonstrates how to perform an asynchronous bulk insert operation using the Skyflow Java SDK. + * The process involves: + * 1. Setting up credentials and vault configuration + * 2. Creating multiple records to be inserted + * 3. Building and executing an async bulk insert request + * 4. Handling the insert response or errors using CompletableFuture + */ +public class BulkInsertAsync { + + public static void main(String[] args) { + try { + // Step 1: Initialize credentials with the path to your service account key file + String filePath = ""; + Credentials credentials = new Credentials(); + credentials.setPath(filePath); + + // Step 2: Configure the vault with required parameters + VaultConfig vaultConfig = new VaultConfig(); + vaultConfig.setVaultId(""); + vaultConfig.setClusterId(""); + vaultConfig.setEnv(Env.PROD); + vaultConfig.setCredentials(credentials); + + // Step 3: Create Skyflow client instance with error logging + Skyflow skyflowClient = Skyflow.builder() + .setLogLevel(LogLevel.ERROR) + .addVaultConfig(vaultConfig) + .build(); + + // Step 4: Prepare first record for insertion + HashMap record1 = new HashMap<>(); + record1.put("", ""); + record1.put("", ""); + + // Step 5: Prepare second record for insertion + HashMap record2 = new HashMap<>(); + record2.put("", ""); + record2.put("", ""); + + // Step 6: Combine records into a single list + ArrayList> values = new ArrayList<>(); + values.add(record1); + values.add(record2); + + // Step 7: Build the insert request with table name and values + InsertRequest request = InsertRequest.builder() + .table("") + .values(values) + .build(); + + // Step 8: Execute the async bulk insert operation and handle response using callbacks + CompletableFuture future = skyflowClient.vault().bulkInsertAsync(request); + // Add success and error callbacks + future.thenAccept(response -> { + System.out.println("Async bulk insert resolved with response:\t" + response); + }).exceptionally(throwable -> { + System.err.println("Async bulk insert rejected with error:\t" + throwable.getMessage()); + throw new CompletionException(throwable); + }); + } catch (Exception e) { + // Step 9: Handle any synchronous errors that occur during setup + System.err.println("Error in Skyflow operations:\t" + e.getMessage()); + } + } +} \ No newline at end of file diff --git a/samples/src/main/java/com/example/vault/BulkInsertSync.java b/samples/src/main/java/com/example/vault/BulkInsertSync.java new file mode 100644 index 00000000..ab27e8c1 --- /dev/null +++ b/samples/src/main/java/com/example/vault/BulkInsertSync.java @@ -0,0 +1,74 @@ +package com.example.vault; + +import com.skyflow.Skyflow; +import com.skyflow.config.Credentials; +import com.skyflow.config.VaultConfig; +import com.skyflow.enums.Env; +import com.skyflow.enums.LogLevel; +import com.skyflow.errors.SkyflowException; +import com.skyflow.vault.data.InsertRequest; +import com.skyflow.vault.data.InsertResponse; + +import java.util.ArrayList; +import java.util.HashMap; + +/** + * This sample demonstrates how to perform a synchronous bulk insert operation using the Skyflow Java SDK. + * The process involves: + * 1. Setting up credentials and vault configuration + * 2. Creating multiple records to be inserted + * 3. Building and executing a bulk insert request + * 4. Handling the insert response or any potential errors + */ +public class BulkInsertSync { + + public static void main(String[] args) { + try { + // Step 1: Initialize credentials with the path to your service account key file + String filePath = ""; + Credentials credentials = new Credentials(); + credentials.setPath(filePath); + + // Step 2: Configure the vault with required parameters + VaultConfig vaultConfig = new VaultConfig(); + vaultConfig.setVaultId(""); + vaultConfig.setClusterId(""); + vaultConfig.setEnv(Env.PROD); + vaultConfig.setCredentials(credentials); + + // Step 3: Create Skyflow client instance with error logging + Skyflow skyflowClient = Skyflow.builder() + .setLogLevel(LogLevel.ERROR) + .addVaultConfig(vaultConfig) + .build(); + + // Step 4: Prepare first record for insertion + HashMap record1 = new HashMap<>(); + record1.put("", ""); + record1.put("", ""); + + // Step 5: Prepare second record for insertion + HashMap record2 = new HashMap<>(); + record2.put("", ""); + record2.put("", ""); + + // Step 6: Combine records into a single list + ArrayList> values = new ArrayList<>(); + values.add(record1); + values.add(record2); + + // Step 7: Build the insert request with table name and values + InsertRequest request = InsertRequest.builder() + .table("") + .values(values) + .build(); + + // Step 8: Execute the bulk insert operation and print the response + InsertResponse response = skyflowClient.vault().bulkInsert(request); + System.out.println(response); + } catch (SkyflowException e) { + // Step 9: Handle any errors that occur during the process + System.err.println("Error in Skyflow operations: " + e.getMessage()); + } + } +} \ No newline at end of file diff --git a/samples/src/main/java/com/example/vault/ClientOperations.java b/samples/src/main/java/com/example/vault/ClientOperations.java deleted file mode 100644 index 7931db34..00000000 --- a/samples/src/main/java/com/example/vault/ClientOperations.java +++ /dev/null @@ -1,95 +0,0 @@ -package com.example.vault; - -import com.skyflow.Skyflow; -import com.skyflow.config.Credentials; -import com.skyflow.config.VaultConfig; -import com.skyflow.enums.Env; -import com.skyflow.enums.LogLevel; -import com.skyflow.errors.SkyflowException; -import com.skyflow.vault.data.DeleteRequest; -import com.skyflow.vault.data.DeleteResponse; - -import java.util.ArrayList; - -/** - * This class demonstrates how to configure and interact with Skyflow vaults using the Skyflow Java SDK. - *

- * The operations performed in this class include: - * 1. Setting up authentication credentials. - * 2. Configuring a primary vault and initializing a Skyflow client. - * 3. Adding a secondary vault to the client. - * 4. Updating vault configuration. - * 5. Updating Skyflow API credentials dynamically. - * 6. Performing a secure deletion of a record in the secondary vault. - * 7. Removing the secondary vault configuration after the operation. - *

- * This example illustrates how to securely manage and delete sensitive data using Skyflow. - */ -public class ClientOperations { - public static void main(String[] args) throws SkyflowException { - // Step 1: Set up authentication credentials for accessing Skyflow vault - Credentials credentials = new Credentials(); - credentials.setToken(""); // Replace with the actual bearer token - // Alternative authentication methods include API key, credentials file path, or credentialsString - - // Step 2: Configure the primary vault with necessary identifiers and credentials - VaultConfig primaryVaultConfig = new VaultConfig(); - primaryVaultConfig.setVaultId(""); // Set first vault ID - primaryVaultConfig.setClusterId(""); // Set first cluster ID - primaryVaultConfig.setEnv(Env.PROD); // Define the environment (e.g., PROD, DEV, STAGE, SANDBOX) - primaryVaultConfig.setCredentials(credentials); // Attach authentication credentials - - // Step 3: Create a Skyflow client instance to interact with the vault - Skyflow skyflowClient = Skyflow.builder() - .setLogLevel(LogLevel.ERROR) // Set logging level (ERROR to reduce verbosity) - .addVaultConfig(primaryVaultConfig) // Associate the primary vault configuration - .build(); // Build the Skyflow client instance - - // Step 4: Configure the secondary vault, which will be used later for deletion operations - VaultConfig secondaryVaultConfig = new VaultConfig(); - secondaryVaultConfig.setVaultId(""); // Set second vault ID - secondaryVaultConfig.setClusterId(""); // Set second cluster ID - secondaryVaultConfig.setEnv(Env.PROD); // Define the environment - - // Add the secondary vault configuration to the existing Skyflow client - skyflowClient.addVaultConfig(secondaryVaultConfig); - - // Step 5: Update the secondary vault configuration with credentials - VaultConfig updatedVaultConfig = new VaultConfig(); - updatedVaultConfig.setVaultId(""); // Ensure update applies to the correct vault - updatedVaultConfig.setClusterId(""); // Maintain correct cluster association - updatedVaultConfig.setCredentials(credentials); // Attach authentication credentials - - // Apply the updated vault configuration - skyflowClient.updateVaultConfig(updatedVaultConfig); - - // Step 6: Update Skyflow API credentials dynamically - Credentials skyflowCredentials = new Credentials(); - skyflowCredentials.setApiKey(""); // Replace with the actual API key - - // Apply the updated credentials to the Skyflow client - skyflowClient.updateSkyflowCredentials(skyflowCredentials); // Used when individual credentials are not provided - - try { - // Step 7: Prepare a delete request to securely remove data from the secondary vault - ArrayList ids = new ArrayList<>(); - ids.add(""); // Replace with the actual ID of the record to delete - - DeleteRequest deleteRequest = DeleteRequest.builder() - .ids(ids) // Specify record IDs targeted for deletion - .table("") // Set the table name from which records should be deleted - .build(); - - // Step 8: Execute the secure delete operation on the secondary vault - DeleteResponse deleteResponse = skyflowClient.vault("").delete(deleteRequest); - System.out.println("Delete Response (Vault 2): " + deleteResponse); - - // Step 9: Remove the secondary vault configuration after the operation is completed - skyflowClient.removeVaultConfig(""); - - } catch (SkyflowException e) { - // Handle any errors that occur during the delete operation - System.out.println("Error during delete operation in vault 2: " + e); - } - } -} diff --git a/samples/src/main/java/com/example/vault/CredentialsOptions.java b/samples/src/main/java/com/example/vault/CredentialsOptions.java deleted file mode 100644 index 8a3ebc6a..00000000 --- a/samples/src/main/java/com/example/vault/CredentialsOptions.java +++ /dev/null @@ -1,84 +0,0 @@ -package com.example.vault; - -import com.skyflow.Skyflow; -import com.skyflow.config.Credentials; -import com.skyflow.config.VaultConfig; -import com.skyflow.enums.Env; -import com.skyflow.enums.LogLevel; -import com.skyflow.errors.SkyflowException; -import com.skyflow.vault.data.DeleteRequest; -import com.skyflow.vault.data.DeleteResponse; - -import java.util.ArrayList; - -/** - * This class demonstrates multiple authentication methods and deletion operations across different Skyflow vaults. - *

- * The operations performed in this class include: - * 1. Setting up authentication credentials with multiple options. - * 2. Configuring primary and secondary vaults. - * 3. Initializing a Skyflow client with multiple vault configurations. - * 4. Performing secure deletion of records from both vaults. - */ -public class CredentialsOptions { - public static void main(String[] args) throws SkyflowException { - // Step 1: Set up authentication credentials using an API key - Credentials credentials = new Credentials(); - credentials.setApiKey(""); // Replace with your actual API key - - // Alternative authentication methods (uncomment if needed) - // credentials.setToken(""); - // credentials.setPath(""); - // credentials.setCredentialsString(""); - - // Step 2: Configure the primary vault - VaultConfig primaryVaultConfig = new VaultConfig(); - primaryVaultConfig.setVaultId(""); // Set first vault ID - primaryVaultConfig.setClusterId(""); // Set first cluster ID - primaryVaultConfig.setEnv(Env.PROD); // Define the environment (e.g., PROD, DEV, STAGE, SANDBOX) - - // Step 3: Configure the secondary vault with credentials - VaultConfig secondaryVaultConfig = new VaultConfig(); - secondaryVaultConfig.setVaultId(""); // Set second vault ID - secondaryVaultConfig.setClusterId(""); // Set second cluster ID - secondaryVaultConfig.setEnv(Env.PROD); // Define the environment - secondaryVaultConfig.setCredentials(credentials); // Attach authentication credentials - - // Step 4: Create a Skyflow client instance with both vault configurations - Skyflow skyflowClient = Skyflow.builder() - .setLogLevel(LogLevel.ERROR) // Set logging level to ERROR - .addVaultConfig(primaryVaultConfig) // Associate the primary vault configuration - .addVaultConfig(secondaryVaultConfig) // Associate the secondary vault configuration - .build(); - - // Step 5: Perform secure deletion from the first vault - try { - ArrayList ids1 = new ArrayList<>(); - ids1.add(""); // Replace with the actual ID to delete - DeleteRequest deleteRequest1 = DeleteRequest.builder() - .ids(ids1) // Specify record IDs targeted for deletion - .table("") // Set the table name from which records should be deleted - .build(); - - DeleteResponse deleteResponse1 = skyflowClient.vault("").delete(deleteRequest1); - System.out.println("Delete Response (Vault 1): " + deleteResponse1); - } catch (SkyflowException e) { - System.out.println("Error during delete operation in Vault 1: " + e); - } - - // Step 6: Perform secure deletion from the second vault - try { - ArrayList ids2 = new ArrayList<>(); - ids2.add(""); // Replace with the actual ID to delete - DeleteRequest deleteRequest2 = DeleteRequest.builder() - .ids(ids2) // Specify record IDs targeted for deletion - .table("") // Set the table name from which records should be deleted - .build(); - - DeleteResponse deleteResponse2 = skyflowClient.vault("").delete(deleteRequest2); - System.out.println("Delete Response (Vault 2): " + deleteResponse2); - } catch (SkyflowException e) { - System.out.println("Error during delete operation in Vault 2: " + e); - } - } -} diff --git a/samples/src/main/java/com/example/vault/DeleteExample.java b/samples/src/main/java/com/example/vault/DeleteExample.java deleted file mode 100644 index 9fe41f61..00000000 --- a/samples/src/main/java/com/example/vault/DeleteExample.java +++ /dev/null @@ -1,64 +0,0 @@ -package com.example.vault; - -import com.skyflow.Skyflow; -import com.skyflow.config.Credentials; -import com.skyflow.config.VaultConfig; -import com.skyflow.enums.Env; -import com.skyflow.enums.LogLevel; -import com.skyflow.errors.SkyflowException; -import com.skyflow.vault.data.DeleteRequest; -import com.skyflow.vault.data.DeleteResponse; - -import java.util.ArrayList; - -/** - * This example demonstrates how to use the Skyflow SDK to delete records from one or more vaults - * by specifying the vault configurations, credentials, and record IDs to delete. - *

- * Steps include: - * 1. Setting up Skyflow credentials. - * 2. Configuring the vault. - * 3. Creating a Skyflow client. - * 4. Setting the log level for debugging and error tracking. - * 5. Deleting records from the specified vault(s) using record IDs and table names. - */ -public class DeleteExample { - public static void main(String[] args) throws SkyflowException { - // Step 1: Set up Skyflow credentials - Credentials credentials = new Credentials(); - credentials.setPath(""); // Replace with the actual path to the credentials file - - // Step 2: Configure the first vault - VaultConfig primaryVaultConfig = new VaultConfig(); - primaryVaultConfig.setVaultId(""); // Replace with the ID of the first vault - primaryVaultConfig.setClusterId(""); // Replace with the cluster ID of the first vault - primaryVaultConfig.setEnv(Env.PROD); // Set the environment (e.g., DEV, STAGE, PROD) - primaryVaultConfig.setCredentials(credentials); // Associate the credentials with the vault - - // Step 3: Set up credentials for the Skyflow client - Credentials skyflowCredentials = new Credentials(); - skyflowCredentials.setCredentialsString(""); // Replace with credentials string - - // Step 4: Create a Skyflow client and add vault configurations - Skyflow skyflowClient = Skyflow.builder() - .setLogLevel(LogLevel.ERROR) // Set log level for debugging and error tracking - .addVaultConfig(primaryVaultConfig) // Add the first vault configuration - .addSkyflowCredentials(skyflowCredentials) // Add general Skyflow credentials - .build(); - - // Step 5: Delete a record from the first vault - try { - ArrayList ids = new ArrayList<>(); - ids.add(""); // Replace with the ID of the record to delete - DeleteRequest deleteRequest = DeleteRequest.builder() - .ids(ids) // Specify the record IDs to delete - .table("") // Replace with the table name - .build(); - - DeleteResponse deleteResponse = skyflowClient.vault().delete(deleteRequest); // Perform the delete operation - System.out.println("Delete Response: " + deleteResponse); - } catch (SkyflowException e) { - System.out.println("Error during delete operation in Vault: " + e); - } - } -} diff --git a/samples/src/main/java/com/example/vault/DetokenizeExample.java b/samples/src/main/java/com/example/vault/DetokenizeExample.java deleted file mode 100644 index b5d87d49..00000000 --- a/samples/src/main/java/com/example/vault/DetokenizeExample.java +++ /dev/null @@ -1,87 +0,0 @@ -package com.example.vault; - -import com.skyflow.Skyflow; -import com.skyflow.config.Credentials; -import com.skyflow.config.VaultConfig; -import com.skyflow.enums.Env; -import com.skyflow.enums.LogLevel; -import com.skyflow.errors.SkyflowException; -import com.skyflow.vault.tokens.DetokenizeData; -import com.skyflow.vault.tokens.DetokenizeRequest; -import com.skyflow.vault.tokens.DetokenizeResponse; - -import java.util.ArrayList; - -/** - * This example demonstrates how to use the Skyflow SDK to detokenize sensitive data. - * The steps include: - * 1. Setting up Skyflow credentials. - * 2. Configuring the vault. - * 3. Creating a Skyflow client. - * 4. Detokenizing tokens from specified vaults. - */ -public class DetokenizeExample { - public static void main(String[] args) throws SkyflowException { - // Step 1: Set up Skyflow credentials - Credentials credentials = new Credentials(); - credentials.setToken(""); // Replace with the actual bearer token - - // Step 2: Configure the first vault - VaultConfig primaryVaultConfig = new VaultConfig(); - primaryVaultConfig.setVaultId(""); // Replace with the ID of the first vault - primaryVaultConfig.setClusterId(""); // Replace with the cluster ID of the first vault - primaryVaultConfig.setEnv(Env.PROD); // Set the environment (e.g., DEV, STAGE, PROD) - primaryVaultConfig.setCredentials(credentials); // Associate the credentials with the vault - - // Step 3: Set up credentials for the Skyflow client - Credentials skyflowCredentials = new Credentials(); - skyflowCredentials.setCredentialsString(""); // Replace with credentials string - - // Step 4: Create a Skyflow client and add vault configurations - Skyflow skyflowClient = Skyflow.builder() - .setLogLevel(LogLevel.ERROR) // Set log level to ERROR to capture only critical logs - .addVaultConfig(primaryVaultConfig) // Add the first vault configuration - .addSkyflowCredentials(skyflowCredentials) // Add general Skyflow credentials - .build(); - - // Step 5: Detokenize tokens from the first vault - try { - ArrayList detokenizeData1 = new ArrayList<>(); - DetokenizeData detokenizeDataRecord1 = new DetokenizeData("", RedactionType.MASKED); // Replace with a token to detokenize with MASKED redaction - DetokenizeData detokenizeDataRecord2 = new DetokenizeData(""); // Replace with another token to detokenize with PLAIN_TEXT redaction - detokenizeData1.add(detokenizeDataRecord1); - detokenizeData1.add(detokenizeDataRecord2); - - DetokenizeRequest detokenizeRequest1 = DetokenizeRequest.builder() - .detokenizeData(detokenizeData1) // Specify the tokens to detokenize with specified redaction types - .continueOnError(true) // Continue processing even if an error occurs for some tokens - .build(); - - DetokenizeResponse detokenizeResponse1 = skyflowClient.vault().detokenize(detokenizeRequest1); // Perform detokenization - System.out.println("Detokenize Response (Vault 1): " + detokenizeResponse1); - } catch (SkyflowException e) { - System.out.println("Error during detokenization in Vault 1:"); - e.printStackTrace(); - } - - // Example 2: Detokenize tokens from the second vault - try { - ArrayList detokenizeData2 = new ArrayList<>(); - DetokenizeData detokenizeDataRecord3 = new DetokenizeData("", RedactionType.DEFAULT); // Replace with a token to detokenize - DetokenizeData detokenizeDataRecord4 = new DetokenizeData(""); // Replace with another token to detokenize - detokenizeData2.add(detokenizeDataRecord3); - detokenizeData2.add(detokenizeDataRecord4); - - DetokenizeRequest detokenizeRequest2 = DetokenizeRequest.builder() - .detokenizeData(detokenizeData2) // Specify the tokens to detokenize with specified redaction types - .continueOnError(false) // Stop processing on the first error - .downloadURL(true) // Specify whether to return URLs for file data type - .build(); - - DetokenizeResponse detokenizeResponse2 = skyflowClient.vault("").detokenize(detokenizeRequest2); // Perform detokenization - System.out.println("Detokenize Response (Vault 2): " + detokenizeResponse2); - } catch (SkyflowException e) { - System.out.println("Error during detokenization in Vault: " + e); - } - } -} diff --git a/samples/src/main/java/com/example/vault/GetExample.java b/samples/src/main/java/com/example/vault/GetExample.java deleted file mode 100644 index 6d300752..00000000 --- a/samples/src/main/java/com/example/vault/GetExample.java +++ /dev/null @@ -1,82 +0,0 @@ -package com.example.vault; - -import com.skyflow.Skyflow; -import com.skyflow.config.Credentials; -import com.skyflow.config.VaultConfig; -import com.skyflow.enums.Env; -import com.skyflow.enums.LogLevel; -import com.skyflow.enums.RedactionType; -import com.skyflow.errors.SkyflowException; -import com.skyflow.vault.data.GetRequest; -import com.skyflow.vault.data.GetResponse; - -import java.util.ArrayList; - -/** - * This example demonstrates how to use the Skyflow SDK to fetch sensitive data securely. - * The steps include: - * 1. Setting up vault configurations. - * 2. Creating a Skyflow client. - * 3. Retrieving records using Skyflow IDs and column values. - */ -public class GetExample { - public static void main(String[] args) throws SkyflowException { - // Step 1: Set up credentials for the first vault configuration - Credentials credentials = new Credentials(); - credentials.setCredentialsString(""); // Replace with the actual credentials string - - // Step 2: Configure the first vault - VaultConfig primaryVaultConfig = new VaultConfig(); - primaryVaultConfig.setVaultId(""); // Replace with the ID of the first vault - primaryVaultConfig.setClusterId(""); // Replace with the cluster ID of the first vault - primaryVaultConfig.setEnv(Env.PROD); // Set the environment (e.g., DEV, STAGE, PROD) - primaryVaultConfig.setCredentials(credentials); // Associate the credentials with the vault - - // Step 3: Set up credentials for the Skyflow client - Credentials skyflowCredentials = new Credentials(); - skyflowCredentials.setCredentialsString(""); // Replace with another credentials string - - // Step 4: Create a Skyflow client and add vault configurations - Skyflow skyflowClient = Skyflow.builder() - .setLogLevel(LogLevel.ERROR) // Set log level to ERROR to minimize log output - .addVaultConfig(primaryVaultConfig) // Add the first vault configuration - .addSkyflowCredentials(skyflowCredentials) // Add general Skyflow credentials - .build(); - - // Example 1: Fetch records by Skyflow IDs from the first vault - try { - ArrayList ids = new ArrayList<>(); - ids.add(""); // Replace with the Skyflow ID to fetch the record - - GetRequest getByIdRequest = GetRequest.builder() - .ids(ids) // Specify the list of Skyflow IDs - .table("") // Replace with the table name - .build(); - - GetResponse getByIdResponse = skyflowClient.vault().get(getByIdRequest); // Fetch via skyflow IDs - System.out.println("Get Response (By ID): " + getByIdResponse); - } catch (SkyflowException e) { - System.out.println("Error during fetch by ID:"); - e.printStackTrace(); - } - - // Example 2: Fetch records by column values from the second vault - try { - ArrayList columnValues = new ArrayList<>(); - columnValues.add(""); // Replace with the column value to fetch the record - - GetRequest getByColumnRequest = GetRequest.builder() - .table("") // Replace with the table name - .columnName("") // Replace with the column name - .columnValues(columnValues) // Specify the list of column values - .redactionType(RedactionType.PLAIN_TEXT) // Fetch the data in plain text format - .build(); - - GetResponse getByColumnResponse = skyflowClient.vault().get(getByColumnRequest); // Fetch via column values - System.out.println("Get Response (By Column): " + getByColumnResponse); - } catch (SkyflowException e) { - System.out.println("Error during fetch by column:"); - e.printStackTrace(); - } - } -} diff --git a/samples/src/main/java/com/example/vault/InsertExample.java b/samples/src/main/java/com/example/vault/InsertExample.java deleted file mode 100644 index 25610b2b..00000000 --- a/samples/src/main/java/com/example/vault/InsertExample.java +++ /dev/null @@ -1,99 +0,0 @@ -package com.example.vault; - -import com.skyflow.Skyflow; -import com.skyflow.config.Credentials; -import com.skyflow.config.VaultConfig; -import com.skyflow.enums.Env; -import com.skyflow.enums.LogLevel; -import com.skyflow.enums.TokenMode; -import com.skyflow.errors.SkyflowException; -import com.skyflow.vault.data.InsertRequest; -import com.skyflow.vault.data.InsertResponse; - -import java.util.ArrayList; -import java.util.HashMap; - -/** - * This example demonstrates how to use the Skyflow SDK to securely insert records into a vault. - * It includes: - * 1. Setting up vault configurations. - * 2. Creating a Skyflow client. - * 3. Performing record insertion with and without TokenMode. - * 4. Using upsert functionality to handle conflicts. - */ -public class InsertExample { - public static void main(String[] args) throws SkyflowException { - // Step 1: Set up credentials for the first vault configuration - Credentials credentials = new Credentials(); - credentials.setApiKey(""); // Replace with the actual API key - - // Step 2: Configure the first vault - VaultConfig primaryVaultConfig = new VaultConfig(); - primaryVaultConfig.setVaultId(""); // Replace with the first vault ID - primaryVaultConfig.setClusterId(""); // Replace with the first vault cluster ID - primaryVaultConfig.setEnv(Env.PROD); // Set the environment (e.g., DEV, STAGE, SANDBOX) - primaryVaultConfig.setCredentials(credentials); // Associate credentials with the vault - - // Step 3: Set up credentials for the Skyflow client - Credentials skyflowCredentials = new Credentials(); - skyflowCredentials.setCredentialsString(""); // Replace with the actual credentials string - - // Step 4: Create a Skyflow client and add vault configurations - Skyflow skyflowClient = Skyflow.builder() - .setLogLevel(LogLevel.ERROR) // Set log level to ERROR to limit output - .addVaultConfig(primaryVaultConfig) // Add the vault configuration - .addSkyflowCredentials(skyflowCredentials) // Add general Skyflow credentials - .build(); - - // Example 1: Insert records into the first vault with TokenMode enabled - try { - ArrayList> values1 = new ArrayList<>(); - HashMap value1 = new HashMap<>(); - value1.put("", ""); // Replace with actual column name and value - value1.put("", ""); // Replace with actual column name and value - values1.add(value1); - - ArrayList> tokens = new ArrayList<>(); - HashMap token = new HashMap<>(); - token.put("", ""); // Replace with actual token value for COLUMN_NAME_2 - tokens.add(token); - - InsertRequest insertRequest = InsertRequest.builder() - .table("") // Replace with the actual table name - .continueOnError(true) // Continue inserting even if some records fail - .tokenMode(TokenMode.ENABLE) // Enable TokenMode for token validation - .values(values1) // Data to insert - .tokens(tokens) // Provide tokens for TokenMode columns - .returnTokens(true) // Return tokens in the response - .build(); - - InsertResponse insertResponse = skyflowClient.vault().insert(insertRequest); // Perform the insertion - System.out.println("Insert Response (TokenMode Enabled): " + insertResponse); - } catch (SkyflowException e) { - System.out.println("Error during insertion with TokenMode enabled:" + e); - } - - // Example 2: Insert records into the first vault with TokenMode disabled and upsert enabled - try { - ArrayList> values2 = new ArrayList<>(); - HashMap value2 = new HashMap<>(); - value2.put("", ""); // Replace with actual column name and value - value2.put("", ""); // Replace with actual column name and value - values2.add(value2); - - InsertRequest upsertRequest = InsertRequest.builder() - .table("") // Replace with the actual table name - .continueOnError(false) // Stop inserting if any record fails - .tokenMode(TokenMode.DISABLE) // Disable TokenMode - .values(values2) // Data to insert - .returnTokens(false) // Do not return tokens - .upsert("") // Replace with the actual column name used for upsert logic - .build(); - - InsertResponse upsertResponse = skyflowClient.vault().insert(upsertRequest); // Perform upsert operation - System.out.println("Insert Response (Upsert Enabled): " + upsertResponse); - } catch (SkyflowException e) { - System.out.println("Error during insertion with upsert enabled:" + e); - } - } -} \ No newline at end of file diff --git a/samples/src/main/java/com/example/vault/QueryExample.java b/samples/src/main/java/com/example/vault/QueryExample.java deleted file mode 100644 index bde5c697..00000000 --- a/samples/src/main/java/com/example/vault/QueryExample.java +++ /dev/null @@ -1,56 +0,0 @@ -package com.example.vault; - -import com.skyflow.Skyflow; -import com.skyflow.config.Credentials; -import com.skyflow.config.VaultConfig; -import com.skyflow.enums.Env; -import com.skyflow.enums.LogLevel; -import com.skyflow.errors.SkyflowException; -import com.skyflow.vault.data.QueryRequest; -import com.skyflow.vault.data.QueryResponse; - -/** - * This example demonstrates how to use the Skyflow SDK to perform secure queries on a vault. - * It includes: - * 1. Setting up vault configurations. - * 2. Creating a Skyflow client. - * 3. Performing SQL queries on the vault. - */ -public class QueryExample { - public static void main(String[] args) throws SkyflowException { - // Step 1: Set up credentials for the vault configuration - Credentials credentials = new Credentials(); - credentials.setApiKey(""); // Replace with the actual API key - - // Step 2: Configure the vault - VaultConfig vaultConfig = new VaultConfig(); - vaultConfig.setVaultId(""); // Replace with the ID of the vault - vaultConfig.setClusterId(""); // Replace with the cluster ID of the vault - vaultConfig.setEnv(Env.PROD); // Set the environment (e.g., DEV, STAGE, PROD) - vaultConfig.setCredentials(credentials); // Associate the credentials with the vault - - // Step 3: Set up credentials for the Skyflow client - Credentials skyflowCredentials = new Credentials(); - skyflowCredentials.setCredentialsString(""); // Replace with the actual credentials string - - // Step 4: Create a Skyflow client and add vault configuration - Skyflow skyflowClient = Skyflow.builder() - .setLogLevel(LogLevel.ERROR) // Set log level to ERROR for minimal logging - .addVaultConfig(vaultConfig) // Add the vault configuration - .addSkyflowCredentials(skyflowCredentials) // Add general Skyflow credentials - .build(); - - // Example: Perform a query on the vault - try { - String query = ""; // Replace with a valid SQL query for the vault - QueryRequest queryRequest = QueryRequest.builder() - .query(query) // Build the query request - .build(); - - QueryResponse queryResponse = skyflowClient.vault().query(queryRequest); // Execute the query - System.out.println("Query Response: " + queryResponse); // Print the query response - } catch (SkyflowException e) { - System.out.println("Error while querying the vault: " + e); - } - } -} diff --git a/samples/src/main/java/com/example/vault/TokenizeExample.java b/samples/src/main/java/com/example/vault/TokenizeExample.java deleted file mode 100644 index 2c390be8..00000000 --- a/samples/src/main/java/com/example/vault/TokenizeExample.java +++ /dev/null @@ -1,63 +0,0 @@ -package com.example.vault; - -import com.skyflow.Skyflow; -import com.skyflow.config.Credentials; -import com.skyflow.config.VaultConfig; -import com.skyflow.enums.Env; -import com.skyflow.enums.LogLevel; -import com.skyflow.errors.SkyflowException; -import com.skyflow.vault.tokens.ColumnValue; -import com.skyflow.vault.tokens.TokenizeRequest; -import com.skyflow.vault.tokens.TokenizeResponse; - -import java.util.ArrayList; - -/** - * This example demonstrates how to use the Skyflow SDK to tokenize data using a vault configuration. - * It includes: - * 1. Setting up a vault configuration. - * 2. Creating a Skyflow client. - * 3. Performing tokenization. - */ -public class TokenizeExample { - public static void main(String[] args) { - try { - // Step 1: Set up credentials - Credentials credentials = new Credentials(); - credentials.setPath(""); // Replace with the path to the credentials file - - // Step 2: Configure the vault - VaultConfig vaultConfig = new VaultConfig(); - vaultConfig.setVaultId(""); // Replace with the vault ID - vaultConfig.setClusterId(""); // Replace with the cluster ID - vaultConfig.setEnv(Env.DEV); // Set the environment (e.g., DEV, STAGE, PROD) - vaultConfig.setCredentials(credentials); // Associate credentials with the vault - - Credentials skyflowCredentials = new Credentials(); - skyflowCredentials.setCredentialsString(""); // Replace with the actual credentials string - - // Step 3: Create a Skyflow client - Skyflow skyflowClient = Skyflow.builder().setLogLevel(LogLevel.ERROR) // Set log level - .addVaultConfig(vaultConfig) // Add vault configuration - .addSkyflowCredentials(skyflowCredentials) // Add general Skyflow credentials - .build(); - - // Step 4: Prepare data for tokenization - ArrayList columnValues = new ArrayList<>(); - columnValues.add(ColumnValue.builder().value("") // Replace with the actual value to tokenize - .columnGroup("") // Replace with the actual column group name - .build()); - columnValues.add(ColumnValue.builder().value("") // Replace with another value to tokenize - .columnGroup("") // Replace with the column group name - .build()); - - // Step 5: Build and execute the tokenization request - TokenizeRequest tokenizeRequest = TokenizeRequest.builder().values(columnValues).build(); - - TokenizeResponse tokenizeResponse = skyflowClient.vault().tokenize(tokenizeRequest); - System.out.println("Tokenization Response: " + tokenizeResponse); - } catch (SkyflowException e) { - System.out.println("Error while tokenizing data for Vault:" + e); - } - } -} diff --git a/samples/src/main/java/com/example/vault/UpdateExample.java b/samples/src/main/java/com/example/vault/UpdateExample.java deleted file mode 100644 index d5c5ed02..00000000 --- a/samples/src/main/java/com/example/vault/UpdateExample.java +++ /dev/null @@ -1,91 +0,0 @@ -package com.example.vault; - -import com.skyflow.Skyflow; -import com.skyflow.config.Credentials; -import com.skyflow.config.VaultConfig; -import com.skyflow.enums.Env; -import com.skyflow.enums.LogLevel; -import com.skyflow.enums.TokenMode; -import com.skyflow.errors.SkyflowException; -import com.skyflow.vault.data.UpdateRequest; -import com.skyflow.vault.data.UpdateResponse; - -import java.util.HashMap; - -/** - * This example demonstrates how to use the Skyflow SDK to securely update records in a vault. - * It includes: - * 1. Setting up vault configurations. - * 2. Creating a Skyflow client. - * 3. Updating records with and without TokenMode. - */ -public class UpdateExample { - public static void main(String[] args) throws SkyflowException { - // Step 1: Set up credentials for the first vault configuration - Credentials credentials = new Credentials(); - credentials.setApiKey(""); // Replace with the actual API key - - // Step 2: Configure the first vault - VaultConfig primaryVaultConfig = new VaultConfig(); - primaryVaultConfig.setVaultId(""); // Replace with the ID of the first vault - primaryVaultConfig.setClusterId(""); // Replace with the cluster ID of the first vault - primaryVaultConfig.setEnv(Env.PROD); // Set the environment (e.g., DEV, STAGE, PROD) - primaryVaultConfig.setCredentials(credentials); // Associate the credentials with the vault - - // Step 3: Set up credentials for the Skyflow client - Credentials skyflowCredentials = new Credentials(); - skyflowCredentials.setCredentialsString(""); // Replace with the actual credentials string - - // Step 4: Create a Skyflow client and add vault configurations - Skyflow skyflowClient = Skyflow.builder() - .setLogLevel(LogLevel.ERROR) // Enable debugging for detailed logs - .addVaultConfig(primaryVaultConfig) // Add the first vault configuration - .addSkyflowCredentials(skyflowCredentials) // Add general Skyflow credentials - .build(); - - // Step 5: Update records with TokenMode enabled - try { - HashMap data1 = new HashMap<>(); - data1.put("skyflow_id", ""); // Replace with the Skyflow ID of the record - data1.put("", ""); // Replace with column name and value to update - data1.put("", ""); // Replace with another column name and value - - HashMap tokens = new HashMap<>(); - tokens.put("", ""); // Replace with the token for COLUMN_NAME_2 - - UpdateRequest updateRequest1 = UpdateRequest.builder() - .table("") // Replace with the table name - .tokenMode(TokenMode.ENABLE) // Enable TokenMode for token validation - .data(data1) // Data to update - .tokens(tokens) // Provide tokens for TokenMode columns - .returnTokens(true) // Return tokens along with the update response - .build(); - - UpdateResponse updateResponse1 = skyflowClient.vault().update(updateRequest1); // Perform the update - System.out.println("Update Response (TokenMode Enabled): " + updateResponse1); - } catch (SkyflowException e) { - System.out.println("Error during update with TokenMode enabled:"); - e.printStackTrace(); - } - - // Step 6: Update records with TokenMode disabled - try { - HashMap data2 = new HashMap<>(); - data2.put("skyflow_id", ""); // Replace with the Skyflow ID of the record - data2.put("", ""); // Replace with column name and value to update - data2.put("", ""); // Replace with another column name and value - - UpdateRequest updateRequest2 = UpdateRequest.builder() - .table("") // Replace with the table name - .tokenMode(TokenMode.DISABLE) // Disable TokenMode - .data(data2) // Data to update - .returnTokens(false) // Do not return tokens - .build(); - - UpdateResponse updateResponse2 = skyflowClient.vault().update(updateRequest2); // Perform the update - System.out.println("Update Response (TokenMode Disabled): " + updateResponse2); - } catch (SkyflowException e) { - System.out.println("Error during update with TokenMode disabled:" + e); - } - } -} diff --git a/v3/pom.xml b/v3/pom.xml index 10af63bc..3ffc3c09 100644 --- a/v3/pom.xml +++ b/v3/pom.xml @@ -11,7 +11,7 @@ com.skyflow skyflow-java - 3.0.0-beta.3-dev.013f144 + 2.0.0-dev.e96d8dc jar ${project.groupId}:${project.artifactId} Skyflow V3 SDK for the Java programming language diff --git a/v3/src/main/java/com/skyflow/Skyflow.java b/v3/src/main/java/com/skyflow/Skyflow.java index 7973c747..ed357bdd 100644 --- a/v3/src/main/java/com/skyflow/Skyflow.java +++ b/v3/src/main/java/com/skyflow/Skyflow.java @@ -56,7 +56,7 @@ public SkyflowClientBuilder() { public SkyflowClientBuilder addVaultConfig(VaultConfig vaultConfig) throws SkyflowException { LogUtil.printInfoLog(InfoLogs.VALIDATING_VAULT_CONFIG.getLog()); - Validations.validateVaultConfig(vaultConfig); + Validations.validateVaultConfiguration(vaultConfig); VaultConfig vaultConfigCopy; try { vaultConfigCopy = (VaultConfig) vaultConfig.clone(); diff --git a/v3/src/main/java/com/skyflow/VaultClient.java b/v3/src/main/java/com/skyflow/VaultClient.java index b43ccd60..41d65e37 100644 --- a/v3/src/main/java/com/skyflow/VaultClient.java +++ b/v3/src/main/java/com/skyflow/VaultClient.java @@ -39,7 +39,7 @@ public class VaultClient { private String token; private String apiKey; - protected VaultClient(VaultConfig vaultConfig, Credentials credentials) { + protected VaultClient(VaultConfig vaultConfig, Credentials credentials) throws SkyflowException { super(); this.vaultConfig = vaultConfig; this.commonCredentials = credentials; @@ -79,8 +79,11 @@ protected void setBearerToken() throws SkyflowException { this.apiClient = this.apiClientBuilder.build(); } - private void updateVaultURL() { - String vaultURL = Utils.getVaultURL(this.vaultConfig.getClusterId(), this.vaultConfig.getEnv()); + private void updateVaultURL() throws SkyflowException { + String vaultURL = Utils.getEnvVaultURL(); + if (vaultURL == null || vaultURL.isEmpty()) { + vaultURL = Utils.getVaultURL(this.vaultConfig.getClusterId(), this.vaultConfig.getEnv()); + } this.apiClientBuilder.url(vaultURL); } @@ -92,11 +95,13 @@ private void prioritiseCredentials() throws SkyflowException { } else if (this.commonCredentials != null) { this.finalCredentials = this.commonCredentials; } else { - Dotenv dotenv = Dotenv.load(); - String sysCredentials = dotenv.get(Constants.ENV_CREDENTIALS_KEY_NAME); + String sysCredentials = System.getenv(Constants.ENV_CREDENTIALS_KEY_NAME); + if (sysCredentials == null) { + Dotenv dotenv = Dotenv.load(); + sysCredentials = dotenv.get(Constants.ENV_CREDENTIALS_KEY_NAME); + } if (sysCredentials == null) { - throw new SkyflowException(ErrorCode.INVALID_INPUT.getCode(), - ErrorMessage.EmptyCredentials.getMessage()); + throw new SkyflowException(ErrorCode.INVALID_INPUT.getCode(), ErrorMessage.EmptyCredentials.getMessage()); } else { this.finalCredentials = new Credentials(); this.finalCredentials.setCredentialsString(sysCredentials); @@ -126,6 +131,7 @@ protected void updateExecutorInHTTP() { .build(); apiClientBuilder.httpClient(httpClient); } + protected InsertRequest getBulkInsertRequestBody(com.skyflow.vault.data.InsertRequest request, VaultConfig config) throws SkyflowException { List> values = request.getValues(); List insertRecordDataList = new ArrayList<>(); @@ -137,12 +143,12 @@ protected InsertRequest getBulkInsertRequestBody(com.skyflow.vault.data.InsertRe .vaultId(config.getVaultId()) .records(insertRecordDataList) .tableName(request.getTable()); - if(request.getUpsert() != null && !request.getUpsert().isEmpty()){ + if (request.getUpsert() != null && !request.getUpsert().isEmpty()) { if (request.getUpsertType() != null) { EnumUpdateType updateType = null; - if(request.getUpsertType() == UpdateType.REPLACE){ + if (request.getUpsertType() == UpdateType.REPLACE) { updateType = EnumUpdateType.REPLACE; - } else if (request.getUpsertType() == UpdateType.REPLACE) { + } else if (request.getUpsertType() == UpdateType.UPDATE) { updateType = EnumUpdateType.UPDATE; } Upsert upsert = Upsert.builder().uniqueColumns(request.getUpsert()).updateType(updateType).build(); @@ -162,7 +168,7 @@ protected com.skyflow.generated.rest.resources.recordservice.requests.Detokenize com.skyflow.generated.rest.resources.recordservice.requests.DetokenizeRequest.builder() .vaultId(this.vaultConfig.getVaultId()) .tokens(tokens); - if (request.getTokenGroupRedactions() != null){ + if (request.getTokenGroupRedactions() != null) { List tokenGroupRedactionsList = new ArrayList<>(); for (com.skyflow.vault.data.TokenGroupRedactions tokenGroupRedactions : request.getTokenGroupRedactions()) { com.skyflow.generated.rest.types.TokenGroupRedactions redactions = diff --git a/v3/src/main/java/com/skyflow/utils/Constants.java b/v3/src/main/java/com/skyflow/utils/Constants.java index e3c56ad3..33da8b27 100644 --- a/v3/src/main/java/com/skyflow/utils/Constants.java +++ b/v3/src/main/java/com/skyflow/utils/Constants.java @@ -2,16 +2,16 @@ public final class Constants extends BaseConstants { public static final String SDK_NAME = "Skyflow Java SDK "; - public static final String SDK_VERSION = "3.0.0-beta.3"; + public static final String SDK_VERSION = "3.0.0-beta.4"; public static final String VAULT_DOMAIN = ".skyvault."; public static final String SDK_PREFIX = SDK_NAME + SDK_VERSION; public static final Integer INSERT_BATCH_SIZE = 50; public static final Integer MAX_INSERT_BATCH_SIZE = 1000; - public static final Integer INSERT_CONCURRENCY_LIMIT = 10; + public static final Integer INSERT_CONCURRENCY_LIMIT = 1; public static final Integer MAX_INSERT_CONCURRENCY_LIMIT = 10; public static final Integer DETOKENIZE_BATCH_SIZE = 50; - public static final Integer DETOKENIZE_CONCURRENCY_LIMIT = 10; + public static final Integer DETOKENIZE_CONCURRENCY_LIMIT = 1; public static final Integer MAX_DETOKENIZE_BATCH_SIZE = 1000; public static final Integer MAX_DETOKENIZE_CONCURRENCY_LIMIT = 10; diff --git a/v3/src/main/java/com/skyflow/utils/Utils.java b/v3/src/main/java/com/skyflow/utils/Utils.java index f2142bd6..468f3ff6 100644 --- a/v3/src/main/java/com/skyflow/utils/Utils.java +++ b/v3/src/main/java/com/skyflow/utils/Utils.java @@ -2,16 +2,23 @@ import com.google.gson.JsonObject; import com.skyflow.enums.Env; +import com.skyflow.errors.ErrorCode; +import com.skyflow.errors.ErrorMessage; +import com.skyflow.errors.SkyflowException; import com.skyflow.generated.rest.core.ApiClientApiException; import com.skyflow.generated.rest.resources.recordservice.requests.DetokenizeRequest; import com.skyflow.generated.rest.types.InsertRecordData; import com.skyflow.generated.rest.types.InsertResponse; import com.skyflow.generated.rest.types.RecordResponseObject; import com.skyflow.generated.rest.types.TokenGroupRedactions; +import com.skyflow.logs.ErrorLogs; +import com.skyflow.utils.logger.LogUtil; import com.skyflow.vault.data.DetokenizeResponse; import com.skyflow.vault.data.ErrorRecord; import com.skyflow.vault.data.Success; import com.skyflow.vault.data.Token; +import io.github.cdimascio.dotenv.Dotenv; +import io.github.cdimascio.dotenv.DotenvException; import java.util.ArrayList; import java.util.HashMap; @@ -239,4 +246,24 @@ public static com.skyflow.vault.data.InsertResponse formatResponse(InsertRespons return formattedResponse; } + public static String getEnvVaultURL() throws SkyflowException { + try { + String vaultURL = System.getenv("VAULT_URL"); + if (vaultURL == null) { + Dotenv dotenv = Dotenv.load(); + vaultURL = dotenv.get("VAULT_URL"); + } + if (vaultURL != null && vaultURL.trim().isEmpty()) { + LogUtil.printErrorLog(ErrorLogs.EMPTY_VAULT_URL.getLog()); + throw new SkyflowException(ErrorCode.INVALID_INPUT.getCode(), ErrorMessage.EmptyVaultUrl.getMessage()); + } else if (vaultURL != null && !vaultURL.startsWith(BaseConstants.SECURE_PROTOCOL)) { + LogUtil.printErrorLog(ErrorLogs.INVALID_VAULT_URL_FORMAT.getLog()); + throw new SkyflowException( ErrorCode.INVALID_INPUT.getCode(), ErrorMessage.InvalidVaultUrlFormat.getMessage()); + } + return vaultURL; + } catch (DotenvException e) { + return null; + } + } + } diff --git a/v3/src/main/java/com/skyflow/utils/validations/Validations.java b/v3/src/main/java/com/skyflow/utils/validations/Validations.java index b7ea4bbd..af2ad382 100644 --- a/v3/src/main/java/com/skyflow/utils/validations/Validations.java +++ b/v3/src/main/java/com/skyflow/utils/validations/Validations.java @@ -1,5 +1,7 @@ package com.skyflow.utils.validations; +import com.skyflow.config.Credentials; +import com.skyflow.config.VaultConfig; import com.skyflow.enums.InterfaceName; import com.skyflow.errors.ErrorCode; import com.skyflow.errors.ErrorMessage; @@ -20,7 +22,6 @@ private Validations() { super(); } - // add validations specific to v3 SDK public static void validateInsertRequest(InsertRequest insertRequest) throws SkyflowException { String table = insertRequest.getTable(); ArrayList> values = insertRequest.getValues(); @@ -46,12 +47,15 @@ public static void validateInsertRequest(InsertRequest insertRequest) throws Sky ErrorLogs.EMPTY_VALUES.getLog(), InterfaceName.INSERT.getName() )); throw new SkyflowException(ErrorCode.INVALID_INPUT.getCode(), ErrorMessage.EmptyValues.getMessage()); - } else if (upsert != null && upsert.isEmpty()){ + } else if (values.size() > 10000) { + LogUtil.printErrorLog(ErrorLogs.RECORD_SIZE_EXCEED.getLog()); + throw new SkyflowException(ErrorCode.INVALID_INPUT.getCode(), ErrorMessage.RecordSizeExceedError.getMessage()); + } else if (upsert != null && upsert.isEmpty()) { LogUtil.printErrorLog(Utils.parameterizedString( - ErrorLogs.EMPTY_UPSERT.getLog(), InterfaceName.INSERT.getName() + ErrorLogs.EMPTY_UPSERT_VALUES.getLog(), InterfaceName.INSERT.getName() )); + throw new SkyflowException(ErrorCode.INVALID_INPUT.getCode(), ErrorMessage.EmptyUpsertValues.getMessage()); } - // upsert for (HashMap valuesMap : values) { for (String key : valuesMap.keySet()) { @@ -82,40 +86,68 @@ public static void validateDetokenizeRequest(DetokenizeRequest request) throws S throw new SkyflowException(ErrorCode.INVALID_INPUT.getCode(), ErrorMessage.DetokenizeRequestNull.getMessage()); } List tokens = request.getTokens(); + if (tokens.size() > 10000) { + LogUtil.printErrorLog(ErrorLogs.TOKENS_SIZE_EXCEED.getLog()); + throw new SkyflowException(ErrorCode.INVALID_INPUT.getCode(), ErrorMessage.TokensSizeExceedError.getMessage()); + } if (tokens == null || tokens.isEmpty()) { LogUtil.printErrorLog(Utils.parameterizedString( ErrorLogs.EMPTY_DETOKENIZE_DATA.getLog(), InterfaceName.DETOKENIZE.getName() - )); - throw new SkyflowException(ErrorCode.INVALID_INPUT.getCode(), ErrorMessage.EmptyDetokenizeData.getMessage()); + )); + throw new SkyflowException(ErrorCode.INVALID_INPUT.getCode(), ErrorMessage.EmptyDetokenizeData.getMessage()); } - for (String token : tokens) { + for (int index = 0; index < tokens.size(); index++) { + String token = tokens.get(index); if (token == null || token.trim().isEmpty()) { LogUtil.printErrorLog(Utils.parameterizedString( - ErrorLogs.EMPTY_OR_NULL_TOKEN_IN_DETOKENIZE_DATA.getLog(), InterfaceName.DETOKENIZE.getName() - )); + ErrorLogs.EMPTY_OR_NULL_TOKEN_IN_DETOKENIZE_DATA.getLog(), + InterfaceName.DETOKENIZE.getName(), + String.valueOf(index))); throw new SkyflowException(ErrorCode.INVALID_INPUT.getCode(), ErrorMessage.EmptyTokenInDetokenizeData.getMessage()); } } + List groupRedactions = request.getTokenGroupRedactions(); if (groupRedactions != null && !groupRedactions.isEmpty()) { - for (TokenGroupRedactions group : groupRedactions) { - if (group == null) { - LogUtil.printErrorLog(Utils.parameterizedString(ErrorLogs.NULL_TOKEN_REDACTION_GROUP_OBJECT.getLog(), InterfaceName.DETOKENIZE.getName())); - throw new SkyflowException(ErrorCode.INVALID_INPUT.getCode(), ErrorMessage.NullTokenGroupRedactions.getMessage()); - } - String groupName = group.getTokenGroupName(); - String redaction = group.getRedaction(); - if (groupName == null || groupName.trim().isEmpty()) { - LogUtil.printErrorLog(Utils.parameterizedString(ErrorLogs.NULL_TOKEN_GROUP_NAME_IN_TOKEN_GROUP.getLog(), InterfaceName.DETOKENIZE.getName())); - throw new SkyflowException(ErrorCode.INVALID_INPUT.getCode(), ErrorMessage.NullTokenGroupNameInTokenGroup.getMessage()); - } - if (redaction == null || redaction.trim().isEmpty()) { - LogUtil.printErrorLog(Utils.parameterizedString(ErrorLogs.EMPTY_OR_NULL_REDACTION_IN_TOKEN_GROUP.getLog(), InterfaceName.DETOKENIZE.getName())); - throw new SkyflowException(ErrorCode.INVALID_INPUT.getCode(), ErrorMessage.NullRedactionInTokenGroup.getMessage()); - } + for (TokenGroupRedactions group : groupRedactions) { + if (group == null) { + LogUtil.printErrorLog(Utils.parameterizedString(ErrorLogs.NULL_TOKEN_REDACTION_GROUP_OBJECT.getLog(), InterfaceName.DETOKENIZE.getName())); + throw new SkyflowException(ErrorCode.INVALID_INPUT.getCode(), ErrorMessage.NullTokenGroupRedactions.getMessage()); + } + String groupName = group.getTokenGroupName(); + String redaction = group.getRedaction(); + if (groupName == null || groupName.trim().isEmpty()) { + LogUtil.printErrorLog(Utils.parameterizedString(ErrorLogs.NULL_TOKEN_GROUP_NAME_IN_TOKEN_GROUP.getLog(), InterfaceName.DETOKENIZE.getName())); + throw new SkyflowException(ErrorCode.INVALID_INPUT.getCode(), ErrorMessage.NullTokenGroupNameInTokenGroup.getMessage()); + } + if (redaction == null || redaction.trim().isEmpty()) { + LogUtil.printErrorLog(Utils.parameterizedString(ErrorLogs.EMPTY_OR_NULL_REDACTION_IN_TOKEN_GROUP.getLog(), InterfaceName.DETOKENIZE.getName())); + throw new SkyflowException(ErrorCode.INVALID_INPUT.getCode(), ErrorMessage.NullRedactionInTokenGroup.getMessage()); } } - + } } + public static void validateVaultConfiguration(VaultConfig vaultConfig) throws SkyflowException { + String vaultId = vaultConfig.getVaultId(); + String clusterId = vaultConfig.getClusterId(); + Credentials credentials = vaultConfig.getCredentials(); + if (vaultId == null) { + LogUtil.printErrorLog(ErrorLogs.VAULT_ID_IS_REQUIRED.getLog()); + throw new SkyflowException(ErrorCode.INVALID_INPUT.getCode(), ErrorMessage.InvalidVaultId.getMessage()); + } else if (vaultId.trim().isEmpty()) { + LogUtil.printErrorLog(ErrorLogs.EMPTY_VAULT_ID.getLog()); + throw new SkyflowException(ErrorCode.INVALID_INPUT.getCode(), ErrorMessage.EmptyVaultId.getMessage()); + } else if (Utils.getEnvVaultURL() == null) { + if (clusterId == null) { + LogUtil.printErrorLog(ErrorLogs.CLUSTER_ID_IS_REQUIRED.getLog()); + throw new SkyflowException(ErrorCode.INVALID_INPUT.getCode(), ErrorMessage.InvalidClusterId.getMessage()); + } else if (clusterId.trim().isEmpty()) { + LogUtil.printErrorLog(ErrorLogs.EMPTY_CLUSTER_ID.getLog()); + throw new SkyflowException(ErrorCode.INVALID_INPUT.getCode(), ErrorMessage.EmptyClusterId.getMessage()); + } + } else if (credentials != null) { + validateCredentials(credentials); + } + } } diff --git a/v3/src/main/java/com/skyflow/vault/controller/VaultController.java b/v3/src/main/java/com/skyflow/vault/controller/VaultController.java index 0ac80f4a..ca54230a 100644 --- a/v3/src/main/java/com/skyflow/vault/controller/VaultController.java +++ b/v3/src/main/java/com/skyflow/vault/controller/VaultController.java @@ -9,6 +9,7 @@ import com.skyflow.generated.rest.core.ApiClientApiException; import com.skyflow.generated.rest.types.InsertRecordData; import com.skyflow.generated.rest.types.InsertResponse; +import com.skyflow.generated.rest.types.Upsert; import com.skyflow.logs.ErrorLogs; import com.skyflow.logs.InfoLogs; import com.skyflow.logs.WarningLogs; @@ -18,12 +19,16 @@ import com.skyflow.utils.validations.Validations; import com.skyflow.vault.data.*; import io.github.cdimascio.dotenv.Dotenv; +import io.github.cdimascio.dotenv.DotenvException; import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; import java.util.List; -import java.util.concurrent.*; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; import static com.skyflow.utils.Utils.*; @@ -34,7 +39,7 @@ public final class VaultController extends VaultClient { private int detokenizeBatchSize; private int detokenizeConcurrencyLimit; - public VaultController(VaultConfig vaultConfig, Credentials credentials) { + public VaultController(VaultConfig vaultConfig, Credentials credentials) throws SkyflowException { super(vaultConfig, credentials); this.insertBatchSize = Constants.INSERT_BATCH_SIZE; this.insertConcurrencyLimit = Constants.INSERT_CONCURRENCY_LIMIT; @@ -125,7 +130,7 @@ public DetokenizeResponse bulkDetokenize(DetokenizeRequest detokenizeRequest) th } } - public CompletableFuture bulkDetokenizeAsync(DetokenizeRequest detokenizeRequest) throws SkyflowException{ + public CompletableFuture bulkDetokenizeAsync(DetokenizeRequest detokenizeRequest) throws SkyflowException { LogUtil.printInfoLog(InfoLogs.DETOKENIZE_TRIGGERED.getLog()); ExecutorService executor = Executors.newFixedThreadPool(detokenizeConcurrencyLimit); try { @@ -161,13 +166,14 @@ public CompletableFuture bulkDetokenizeAsync(DetokenizeReque executor.shutdown(); return new DetokenizeResponse(successRecords, errorTokens, detokenizeRequest.getTokens()); }); - } catch (Exception e){ + } catch (Exception e) { LogUtil.printErrorLog(ErrorLogs.DETOKENIZE_REQUEST_REJECTED.getLog()); throw new SkyflowException(e.getMessage()); } finally { executor.shutdown(); } } + private com.skyflow.vault.data.InsertResponse processSync( com.skyflow.generated.rest.resources.recordservice.requests.InsertRequest insertRequest, ArrayList> originalPayload @@ -207,11 +213,11 @@ private DetokenizeResponse processDetokenizeSync( List batches = Utils.createDetokenizeBatches(detokenizeRequest, detokenizeBatchSize); try { List> futures = this.detokenizeBatchFutures(executor, batches, errorTokens); - try{ + try { CompletableFuture allFutures = CompletableFuture.allOf(futures.toArray(new CompletableFuture[0])); allFutures.join(); - } catch (Exception e){ + } catch (Exception e) { } for (CompletableFuture future : futures) { DetokenizeResponse futureResponse = future.get(); @@ -224,7 +230,7 @@ private DetokenizeResponse processDetokenizeSync( } } } - } catch (Exception e){ + } catch (Exception e) { LogUtil.printErrorLog(ErrorLogs.DETOKENIZE_REQUEST_REJECTED.getLog()); throw new SkyflowException(e.getMessage()); } finally { @@ -240,7 +246,7 @@ private List> detokenizeBatchFutures(Execu try { for (int batchIndex = 0; batchIndex < batches.size(); batchIndex++) { - com.skyflow.generated.rest.resources.recordservice.requests.DetokenizeRequest batch = batches.get(batchIndex); + com.skyflow.generated.rest.resources.recordservice.requests.DetokenizeRequest batch = batches.get(batchIndex); int batchNumber = batchIndex; CompletableFuture future = CompletableFuture .supplyAsync(() -> processDetokenizeBatch(batch), executor) @@ -251,12 +257,13 @@ private List> detokenizeBatchFutures(Execu }); futures.add(future); } - } catch (Exception e){ + } catch (Exception e) { ErrorRecord errorRecord = new ErrorRecord(0, e.getMessage(), 500); errorTokens.add(errorRecord); } return futures; } + private com.skyflow.generated.rest.types.DetokenizeResponse processDetokenizeBatch(com.skyflow.generated.rest.resources.recordservice.requests.DetokenizeRequest batch) { return this.getRecordsApi().detokenize(batch); } @@ -270,13 +277,14 @@ private com.skyflow.generated.rest.types.DetokenizeResponse processDetokenizeBat ExecutorService executor = Executors.newFixedThreadPool(insertConcurrencyLimit); List> batches = Utils.createBatches(records, insertBatchSize); List> futures = new ArrayList<>(); + Upsert upsert = insertRequest.getUpsert().isPresent() ? insertRequest.getUpsert().get() : null; try { for (int batchIndex = 0; batchIndex < batches.size(); batchIndex++) { List batch = batches.get(batchIndex); int batchNumber = batchIndex; CompletableFuture future = CompletableFuture - .supplyAsync(() -> insertBatch(batch, insertRequest.getTableName().get()), executor) + .supplyAsync(() -> insertBatch(batch, insertRequest.getTableName().get(), upsert), executor) .thenApply(response -> formatResponse(response, batchNumber, insertBatchSize)) .exceptionally(ex -> { errorRecords.addAll(handleBatchException(ex, batch, batchNumber)); @@ -290,20 +298,34 @@ private com.skyflow.generated.rest.types.DetokenizeResponse processDetokenizeBat return futures; } - private InsertResponse insertBatch(List batch, String tableName) { + private InsertResponse insertBatch(List batch, String tableName, Upsert upsert) { com.skyflow.generated.rest.resources.recordservice.requests.InsertRequest req = com.skyflow.generated.rest.resources.recordservice.requests.InsertRequest.builder() .vaultId(this.getVaultConfig().getVaultId()) .tableName(tableName) .records(batch) + .upsert(upsert) .build(); return this.getRecordsApi().insert(req); } private void configureInsertConcurrencyAndBatchSize(int totalRequests) { try { - Dotenv dotenv = Dotenv.load(); - String userProvidedBatchSize = dotenv.get("INSERT_BATCH_SIZE"); - String userProvidedConcurrencyLimit = dotenv.get("INSERT_CONCURRENCY_LIMIT"); + String userProvidedBatchSize = System.getenv("INSERT_BATCH_SIZE"); + String userProvidedConcurrencyLimit = System.getenv("INSERT_CONCURRENCY_LIMIT"); + + Dotenv dotenv = null; + try { + dotenv = Dotenv.load(); + } catch (DotenvException ignored) { + // ignore the case if .env file is not found + } + + if (userProvidedBatchSize == null && dotenv != null) { + userProvidedBatchSize = dotenv.get("INSERT_BATCH_SIZE"); + } + if (userProvidedConcurrencyLimit == null && dotenv != null) { + userProvidedConcurrencyLimit = dotenv.get("INSERT_CONCURRENCY_LIMIT"); + } if (userProvidedBatchSize != null) { try { @@ -357,9 +379,22 @@ private void configureInsertConcurrencyAndBatchSize(int totalRequests) { private void configureDetokenizeConcurrencyAndBatchSize(int totalRequests) { try { - Dotenv dotenv = Dotenv.load(); - String userProvidedBatchSize = dotenv.get("DETOKENIZE_BATCH_SIZE"); - String userProvidedConcurrencyLimit = dotenv.get("DETOKENIZE_CONCURRENCY_LIMIT"); + String userProvidedBatchSize = System.getenv("DETOKENIZE_BATCH_SIZE"); + String userProvidedConcurrencyLimit = System.getenv("DETOKENIZE_BATCH_SIZE"); + + Dotenv dotenv = null; + try { + dotenv = Dotenv.load(); + } catch (DotenvException ignored) { + // ignore the case if .env file is not found + } + + if (userProvidedBatchSize == null && dotenv != null) { + userProvidedBatchSize = dotenv.get("DETOKENIZE_BATCH_SIZE"); + } + if (userProvidedConcurrencyLimit == null && dotenv != null) { + userProvidedConcurrencyLimit = dotenv.get("DETOKENIZE_BATCH_SIZE"); + } if (userProvidedBatchSize != null) { try { diff --git a/v3/test/java/com/skyflow/vault/controller/VaultControllerTests.java b/v3/test/java/com/skyflow/vault/controller/VaultControllerTests.java index 7ffa1d3a..605d29eb 100644 --- a/v3/test/java/com/skyflow/vault/controller/VaultControllerTests.java +++ b/v3/test/java/com/skyflow/vault/controller/VaultControllerTests.java @@ -2,21 +2,30 @@ import com.skyflow.config.Credentials; import com.skyflow.config.VaultConfig; +import com.skyflow.errors.ErrorCode; +import com.skyflow.errors.ErrorMessage; import com.skyflow.errors.SkyflowException; import com.skyflow.utils.Constants; import com.skyflow.utils.validations.Validations; import com.skyflow.vault.data.InsertRequest; -import org.junit.*; +import org.junit.After; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; + import java.io.FileWriter; import java.io.IOException; -import java.lang.reflect.Method; import java.lang.reflect.Field; -import java.util.*; +import java.lang.reflect.Method; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Scanner; + import static org.junit.Assert.*; public class VaultControllerTests { - private static final String ENV_PATH = "/home/saib/skyflow3/skyflow-java/v3/.env"; + private static final String ENV_PATH = "./.env"; private VaultConfig vaultConfig; private Credentials credentials; @@ -42,14 +51,28 @@ public void tearDown() { } private void writeEnv(String content) { - try (FileWriter writer = new FileWriter(ENV_PATH)) { + java.io.File envFile = new java.io.File(ENV_PATH); + java.io.File parentDir = envFile.getParentFile(); + if (parentDir != null && !parentDir.exists()) { + parentDir.mkdirs(); // Create parent directory if it doesn't exist + } + try (FileWriter writer = new FileWriter(envFile)) { writer.write(content); } catch (IOException e) { throw new RuntimeException(e); } + // Print the contents of the .env file + try (Scanner scanner = new Scanner(envFile)) { + System.out.println("Current .env contents:"); + while (scanner.hasNextLine()) { + System.out.println(scanner.nextLine()); + } + } catch (IOException e) { + System.out.println("Could not read .env file: " + e.getMessage()); + } } - private VaultController createController() { + private VaultController createController() throws SkyflowException { return new VaultController(vaultConfig, credentials); } @@ -66,7 +89,7 @@ private void invokeConfigureInsertConcurrencyAndBatchSize(VaultController contro method.invoke(controller, totalRequests); } - private ArrayList> generateValues(int noOfRecords){ + private ArrayList> generateValues(int noOfRecords) { ArrayList> values = new ArrayList<>(); for (int i = 0; i < noOfRecords; i++) { values.add(new HashMap<>()); @@ -121,9 +144,19 @@ public void testValidation_valuesIsEmpty() { @Test public void testValidation_upsertIsEmpty() throws SkyflowException { - InsertRequest req = InsertRequest.builder().table("table1").values(generateValues(1)).upsert(new ArrayList<>()).build(); - // Should not throw, just logs a warning - Validations.validateInsertRequest(req); + try { + InsertRequest req = InsertRequest.builder() + .table("table1") + .values(generateValues(1)) + .upsert(new ArrayList<>()) + .build(); + Validations.validateInsertRequest(req); + } catch (SkyflowException e) { + Assert.assertEquals(ErrorCode.INVALID_INPUT.getCode(), e.getHttpCode()); + Assert.assertEquals(ErrorMessage.EmptyUpsertValues.getMessage(), e.getMessage()); + } catch (Exception e) { + Assert.fail(e.getMessage()); + } } @@ -285,8 +318,6 @@ public void testConcurrencyZeroOrNegative() throws Exception { assertEquals(min, getPrivateInt(controller, "insertConcurrencyLimit")); - - writeEnv("INSERT_CONCURRENCY_LIMIT=-5"); try { @@ -342,7 +373,8 @@ public void testHighConcurrencyForLowRecords() throws Exception { try { controller.bulkInsert(insertRequest); - } catch (Exception ignored) {} + } catch (Exception ignored) { + } // Only 10 batches needed, so concurrency should be clamped to 10 assertEquals(1000, getPrivateInt(controller, "insertBatchSize")); @@ -354,15 +386,16 @@ public void testHighConcurrencyForLowRecords() throws Exception { public void testFractionalLastBatch() throws Exception { writeEnv("INSERT_BATCH_SIZE=100"); VaultController controller = createController(); - InsertRequest insertRequest = InsertRequest.builder().table("table1").values(generateValues(10050)).build(); + InsertRequest insertRequest = InsertRequest.builder().table("table1").values(generateValues(9050)).build(); try { controller.bulkInsert(insertRequest); - } catch (Exception ignored) {} + } catch (Exception ignored) { + } // Last batch should have 50 records, concurrency should be 101 assertEquals(100, getPrivateInt(controller, "insertBatchSize")); - assertEquals(10, getPrivateInt(controller, "insertConcurrencyLimit")); + assertEquals(Constants.INSERT_CONCURRENCY_LIMIT.intValue(), getPrivateInt(controller, "insertConcurrencyLimit")); } private int getPrivateInt(Object obj, String field) throws Exception { diff --git a/v3/test/java/com/skyflow/vault/data/InsertTests.java b/v3/test/java/com/skyflow/vault/data/InsertTests.java index 7ea17d89..ff71fa19 100644 --- a/v3/test/java/com/skyflow/vault/data/InsertTests.java +++ b/v3/test/java/com/skyflow/vault/data/InsertTests.java @@ -211,11 +211,11 @@ public void testEmptyUpsertInInsertRequestValidations() { InsertRequest request = InsertRequest.builder().table(table).values(values).upsert(new ArrayList<>()).build(); try { Validations.validateInsertRequest(request); -// Assert.fail(EXCEPTION_NOT_THROWN); + Assert.fail(EXCEPTION_NOT_THROWN); } catch (SkyflowException e) { Assert.assertEquals(ErrorCode.INVALID_INPUT.getCode(), e.getHttpCode()); Assert.assertEquals( - Utils.parameterizedString(ErrorMessage.EmptyUpsert.getMessage(), Constants.SDK_PREFIX), + Utils.parameterizedString(ErrorMessage.EmptyUpsertValues.getMessage(), Constants.SDK_PREFIX), e.getMessage() ); }