Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
109 changes: 109 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ SDK for the Skyflow Data Privacy Vault.
- [Generate bearer tokens with context](#generate-bearer-tokens-with-context)
- [Generate scoped bearer tokens](#generate-scoped-bearer-tokens)
- [Generate signed data tokens](#generate-signed-data-tokens)
- [Bearer token expiry edge case](#bearer-token-expiry-edge-case)
- [Logging](#logging)
- [Reporting a vulnerability](#reporting-a-vulnerability)

Expand Down Expand Up @@ -2432,6 +2433,114 @@ Notes:
- The `timeToLive` (TTL) value should be specified in seconds.
- By default, the TTL value is set to 60 seconds.

#### Bearer token expiry edge case
When you use bearer tokens for authentication and API requests in SDKs, there's the potential for a token to expire after the token is verified as valid but before the actual API call is made, causing the request to fail unexpectedly due to the token's expiration. An error from this edge case would look something like this:

```txt
message: Authentication failed. Bearer token is expired. Use a valid bearer token. See https://docs.skyflow.com/api-authentication/
```

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-node/blob/v2/samples/service-account/bearer-token-expiry-example.ts.ts):

```javascript
import {
Credentials,
DetokenizeOptions,
DetokenizeRequest,
DetokenizeResponse,
Env,
LogLevel,
RedactionType,
Skyflow,
SkyflowError,
VaultConfig,
SkyflowConfig
} from 'skyflow-node';

/**
* 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).
*/
async function detokenizeData(skyflowClient: Skyflow, vaultId: string) {
try {
// Creating a list of tokens to be detokenized
const detokenizeData: Array<string> = ['<YOUR_TOKEN_VALUE_1>', '<YOUR_TOKEN_VALUE_2>'];

// Building a detokenization request
const detokenizeRequest: DetokenizeRequest = new DetokenizeRequest(
detokenizeData,
RedactionType.PLAIN_TEXT // Redaction type (e.g., PLAIN_TEXT)
);

// Configuring detokenization options
const detokenizeOptions: DetokenizeOptions = new DetokenizeOptions();
detokenizeOptions.setContinueOnError(false); // Stop on error
detokenizeOptions.setDownloadURL(false); // Disable download URL generation

// Sending the detokenization request and receiving the response
const response: DetokenizeResponse = await skyflowClient
.vault(vaultId)
.detokenize(detokenizeRequest, detokenizeOptions);

// Printing the detokenized response
console.log('Detokenization successful:', response);
} catch (err) {
throw err;
}
}

async function main() {
try {
// Setting up credentials for accessing the Skyflow vault
const credentials: Credentials = {
credentialsString: '<YOUR_CREDENTIALS_STRING>', // Credentials string for authentication
};

// Configuring the Skyflow vault with necessary details
const primaryVaultConfig: VaultConfig = {
vaultId: '<YOUR_VAULT_ID>', // Vault ID
clusterId: '<YOUR_CLUSTER_ID>', // Cluster ID
env: Env.PROD, // Environment set to PROD
credentials: credentials // Setting credentials
};

// Creating a Skyflow client instance with the configured vault
const skyflowConfig: SkyflowConfig = {
vaultConfigs: [primaryVaultConfig],
logLevel: LogLevel.ERROR, // Setting log level to ERROR
};

const skyflowClient: Skyflow = new Skyflow(skyflowConfig);

// Attempting to detokenize data using the Skyflow client
try {
await detokenizeData(skyflowClient, primaryVaultConfig.vaultId);
} catch (err) {
// Retry detokenization if the error is due to unauthorized access (HTTP 401)
if (err instanceof SkyflowError && err.error?.http_code === 401) {
console.warn('Unauthorized access detected. Retrying...');
await detokenizeData(skyflowClient, primaryVaultConfig.vaultId);
} else {
// Rethrow the exception for other error codes
throw err;
}
}
} catch (err) {
// Handling any exceptions that occur during the process
console.error('An error occurred:', err);
}
}

// Invoke the main function
main();

```

## Logging

The SDK provides useful logging. By default the logging level of the SDK is set to `LogLevel.ERROR`. This can be changed by setting the `logLevel` in Skyflow Config while creating the Skyflow Client as shown below:
Expand Down
93 changes: 93 additions & 0 deletions samples/service-account/bearer-token-expiry-example.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
import {
Credentials,
DetokenizeOptions,
DetokenizeRequest,
DetokenizeResponse,
Env,
LogLevel,
RedactionType,
Skyflow,
SkyflowError,
VaultConfig,
SkyflowConfig
} from 'skyflow-node';

/**
* 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).
*/
async function detokenizeData(skyflowClient: Skyflow, vaultId: string) {
try {
// Creating a list of tokens to be detokenized
const detokenizeData: Array<string> = ['<YOUR_TOKEN_VALUE_1>', '<YOUR_TOKEN_VALUE_2>'];

// Building a detokenization request
const detokenizeRequest: DetokenizeRequest = new DetokenizeRequest(
detokenizeData,
RedactionType.PLAIN_TEXT // Redaction type (e.g., PLAIN_TEXT)
);

// Configuring detokenization options
const detokenizeOptions: DetokenizeOptions = new DetokenizeOptions();
detokenizeOptions.setContinueOnError(false); // Stop on error
detokenizeOptions.setDownloadURL(false); // Disable download URL generation

// Sending the detokenization request and receiving the response
const response: DetokenizeResponse = await skyflowClient
.vault(vaultId)
.detokenize(detokenizeRequest, detokenizeOptions);

// Printing the detokenized response
console.log('Detokenization successful:', response);
} catch (err) {
throw err;
}
}

async function main() {
try {
// Setting up credentials for accessing the Skyflow vault
const credentials: Credentials = {
credentialsString: '<YOUR_CREDENTIALS_STRING>', // Credentials string for authentication
};

// Configuring the Skyflow vault with necessary details
const primaryVaultConfig: VaultConfig = {
vaultId: '<YOUR_VAULT_ID>', // Vault ID
clusterId: '<YOUR_CLUSTER_ID>', // Cluster ID
env: Env.PROD, // Environment set to PROD
credentials: credentials // Setting credentials
};

// Creating a Skyflow client instance with the configured vault
const skyflowConfig: SkyflowConfig = {
vaultConfigs: [primaryVaultConfig],
logLevel: LogLevel.ERROR, // Setting log level to ERROR
};

const skyflowClient: Skyflow = new Skyflow(skyflowConfig);

// Attempting to detokenize data using the Skyflow client
try {
await detokenizeData(skyflowClient, primaryVaultConfig.vaultId);
} catch (err) {
// Retry detokenization if the error is due to unauthorized access (HTTP 401)
if (err instanceof SkyflowError && err.error?.http_code === 401) {
console.warn('Unauthorized access detected. Retrying...');
await detokenizeData(skyflowClient, primaryVaultConfig.vaultId);
} else {
// Rethrow the exception for other error codes
throw err;
}
}
} catch (err) {
// Handling any exceptions that occur during the process
console.error('An error occurred:', err);
}
}

// Invoke the main function
main();
Loading