Skip to content

Commit 0a3d713

Browse files
SK-2777: Update Fern client re-initialisation (#300)
* SK-2777: update client re-init logic
1 parent 9d69e23 commit 0a3d713

15 files changed

Lines changed: 419 additions & 214 deletions

File tree

README.md

Lines changed: 61 additions & 102 deletions
Original file line numberDiff line numberDiff line change
@@ -2771,73 +2771,59 @@ public class BearerTokenGenerationExample {
27712771

27722772
## Generate bearer tokens with context
27732773

2774-
**Context-aware authorization** embeds context values into a bearer token during its generation and so you can reference those values in your policies. This enables more flexible access controls, such as helping you track end-user identity when making API calls using service accounts, and facilitates using signed data tokens during detokenization. .
2774+
**Context-aware authorization** embeds context values into a bearer token during its generation so you can reference those values in your policies. This enables more flexible access controls, such as helping you track end-user identity when making API calls using service accounts, and facilitates using signed data tokens during detokenization.
27752775

27762776
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.
27772777

2778-
[Example](https://github.com/skyflowapi/skyflow-java/blob/main/samples/src/main/java/com/example/serviceaccount/BearerTokenGenerationWithContextExample.java):
2778+
The `setCtx()` method accepts either a **String** or a **`Map<String, Object>`**:
2779+
2780+
**String context** — use when your policy references a single context value:
27792781

27802782
```java
2781-
import com.skyflow.errors.SkyflowException;
2782-
import com.skyflow.serviceaccount.util.BearerToken;
2783+
BearerToken token = BearerToken.builder()
2784+
.setCredentials(new File(filePath))
2785+
.setCtx("user_12345")
2786+
.build();
2787+
```
27832788

2784-
import java.io.File;
2789+
**JSON object context** — use when your policy needs multiple context values for conditional data access. Each key in the `Map` maps to a Skyflow CEL policy variable under `request.context.*`:
27852790

2786-
/**
2787-
* Example program to generate a Bearer Token using Skyflow's BearerToken utility.
2788-
* The token is generated using two approaches:
2789-
* 1. By providing the credentials.json file path.
2790-
* 2. By providing the contents of credentials.json as a string.
2791-
*/
2792-
public class BearerTokenGenerationWithContextExample {
2793-
public static void main(String[] args) {
2794-
// Variable to store the generated Bearer Token
2795-
String bearerToken = null;
2791+
```java
2792+
Map<String, Object> ctx = new HashMap<>();
2793+
ctx.put("role", "admin");
2794+
ctx.put("department", "finance");
2795+
ctx.put("user_id", "user_12345");
27962796

2797-
// Approach 1: Generate Bearer Token by specifying the path to the credentials.json file
2798-
try {
2799-
// Replace <YOUR_CREDENTIALS_FILE_PATH> with the full path to your credentials.json file
2800-
String filePath = "<YOUR_CREDENTIALS_FILE_PATH>";
2797+
BearerToken token = BearerToken.builder()
2798+
.setCredentials(new File(filePath))
2799+
.setCtx(ctx)
2800+
.build();
2801+
```
28012802

2802-
// Create a BearerToken object using the file path
2803-
BearerToken token = BearerToken.builder()
2804-
.setCredentials(new File(filePath)) // Set credentials using a File object
2805-
.setCtx("abc") // Set context string (example: "abc")
2806-
.build(); // Build the BearerToken object
2803+
With the map above, your Skyflow policies can reference `request.context.role`, `request.context.department`, and `request.context.user_id` to make conditional access decisions.
28072804

2808-
// Retrieve the Bearer Token as a string
2809-
bearerToken = token.getBearerToken();
2805+
You can also set context on `Credentials` for automatic token generation:
28102806

2811-
// Print the generated Bearer Token to the console
2812-
System.out.println(bearerToken);
2813-
} catch (SkyflowException e) {
2814-
// Handle exceptions specific to Skyflow operations
2815-
e.printStackTrace();
2816-
}
2807+
```java
2808+
// String context
2809+
Credentials credentials = new Credentials();
2810+
credentials.setPath("path/to/credentials.json");
2811+
credentials.setContext("user_12345");
28172812

2818-
// Approach 2: Generate Bearer Token by specifying the contents of credentials.json as a string
2819-
try {
2820-
// Replace <YOUR_CREDENTIALS_FILE_CONTENTS_AS_STRING> with the actual contents of your credentials.json file
2821-
String fileContents = "<YOUR_CREDENTIALS_FILE_CONTENTS_AS_STRING>";
2813+
// Map context
2814+
Map<String, Object> ctx = new HashMap<>();
2815+
ctx.put("role", "admin");
2816+
ctx.put("department", "finance");
2817+
credentials.setContext(ctx);
2818+
```
28222819

2823-
// Create a BearerToken object using the file contents as a string
2824-
BearerToken token = BearerToken.builder()
2825-
.setCredentials(fileContents) // Set credentials using a string representation of the file
2826-
.setCtx("abc") // Set context string (example: "abc")
2827-
.build(); // Build the BearerToken object
2820+
> **Note:** `getContext()` returns `Object` — callers should use `instanceof` if they need to inspect the type.
28282821
2829-
// Retrieve the Bearer Token as a string
2830-
bearerToken = token.getBearerToken();
2822+
Context map keys must contain only alphanumeric characters and underscores (`[a-zA-Z0-9_]`). Invalid keys will throw a `SkyflowException`.
28312823

2832-
// Print the generated Bearer Token to the console
2833-
System.out.println(bearerToken);
2834-
} catch (SkyflowException e) {
2835-
// Handle exceptions specific to Skyflow operations
2836-
e.printStackTrace();
2837-
}
2838-
}
2839-
}
2840-
```
2824+
[Full example](https://github.com/skyflowapi/skyflow-java/blob/main/samples/src/main/java/com/example/serviceaccount/BearerTokenGenerationWithContextExample.java)
2825+
2826+
See Skyflow's [context-aware authorization](https://docs.skyflow.com) and [conditional data access](https://docs.skyflow.com) docs for policy variable syntax like `request.context.*`.
28412827

28422828
## Generate scoped bearer tokens
28432829

@@ -2903,58 +2889,31 @@ with the private key of the service account credentials, which adds an additiona
29032889
be detokenized by passing the signed data token and a bearer token generated from service account credentials. The
29042890
service account must have appropriate permissions and context to detokenize the signed data tokens.
29052891

2906-
[Example](https://github.com/skyflowapi/skyflow-java/blob/main/samples/src/main/java/com/example/serviceaccount/SignedTokenGenerationExample.java):
2892+
The `setCtx()` method on `SignedDataTokensBuilder` also accepts either a **String** or a **`Map<String, Object>`**, using the same format as bearer tokens:
29072893

29082894
```java
2909-
import com.skyflow.errors.SkyflowException;
2910-
import com.skyflow.serviceaccount.util.SignedDataTokenResponse;
2911-
import com.skyflow.serviceaccount.util.SignedDataTokens;
2912-
2913-
import java.io.File;
2914-
import java.util.ArrayList;
2915-
import java.util.List;
2916-
2917-
public class SignedTokenGenerationExample {
2918-
public static void main(String[] args) {
2919-
List<SignedDataTokenResponse> signedTokenValues;
2920-
// Generate Signed data token with context by specifying credentials.json file path
2921-
try {
2922-
String filePath = "<YOUR_CREDENTIALS_FILE_PATH>";
2923-
String context = "abc";
2924-
ArrayList<String> dataTokens = new ArrayList<>();
2925-
dataTokens.add("YOUR_DATA_TOKEN_1");
2926-
SignedDataTokens signedToken = SignedDataTokens.builder()
2927-
.setCredentials(new File(filePath))
2928-
.setCtx(context)
2929-
.setTimeToLive(30) // in seconds
2930-
.setDataTokens(dataTokens)
2931-
.build();
2932-
signedTokenValues = signedToken.getSignedDataTokens();
2933-
System.out.println(signedTokenValues);
2934-
} catch (SkyflowException e) {
2935-
e.printStackTrace();
2936-
}
2937-
2938-
// Generate Signed data token with context by specifying credentials.json as string
2939-
try {
2940-
String fileContents = "<YOUR_CREDENTIALS_FILE_CONTENTS_AS_STRING>";
2941-
String context = "abc";
2942-
ArrayList<String> dataTokens = new ArrayList<>();
2943-
dataTokens.add("YOUR_DATA_TOKEN_1");
2944-
SignedDataTokens signedToken = SignedDataTokens.builder()
2945-
.setCredentials(fileContents)
2946-
.setCtx(context)
2947-
.setTimeToLive(30) // in seconds
2948-
.setDataTokens(dataTokens)
2949-
.build();
2950-
signedTokenValues = signedToken.getSignedDataTokens();
2951-
System.out.println(signedTokenValues);
2952-
} catch (SkyflowException e) {
2953-
e.printStackTrace();
2954-
}
2955-
}
2956-
}
2957-
```
2895+
// String context
2896+
SignedDataTokens signedToken = SignedDataTokens.builder()
2897+
.setCredentials(new File(filePath))
2898+
.setCtx("user_12345")
2899+
.setTimeToLive(30)
2900+
.setDataTokens(dataTokens)
2901+
.build();
2902+
2903+
// JSON object context
2904+
Map<String, Object> ctx = new HashMap<>();
2905+
ctx.put("role", "analyst");
2906+
ctx.put("department", "research");
2907+
2908+
SignedDataTokens signedToken = SignedDataTokens.builder()
2909+
.setCredentials(new File(filePath))
2910+
.setCtx(ctx)
2911+
.setTimeToLive(30)
2912+
.setDataTokens(dataTokens)
2913+
.build();
2914+
```
2915+
2916+
[Full example](https://github.com/skyflowapi/skyflow-java/blob/main/samples/src/main/java/com/example/serviceaccount/SignedTokenGenerationExample.java)
29582917

29592918
Response:
29602919

samples/src/main/java/com/example/serviceaccount/BearerTokenGenerationWithContextExample.java

Lines changed: 39 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -4,57 +4,69 @@
44
import com.skyflow.serviceaccount.util.BearerToken;
55

66
import java.io.File;
7+
import java.util.HashMap;
8+
import java.util.Map;
79

810
/**
911
* Example program to generate a Bearer Token using Skyflow's BearerToken utility.
10-
* The token is generated using two approaches:
11-
* 1. By providing the credentials.json file path.
12-
* 2. By providing the contents of credentials.json as a string.
12+
* The token is generated using three approaches:
13+
* 1. By providing a string context.
14+
* 2. By providing a JSON object context (Map) for conditional data access policies.
15+
* 3. By providing the credentials as a string with context.
1316
*/
1417
public class BearerTokenGenerationWithContextExample {
1518
public static void main(String[] args) {
16-
// Variable to store the generated Bearer Token
1719
String bearerToken = null;
1820

19-
// Approach 1: Generate Bearer Token by specifying the path to the credentials.json file
21+
// Approach 1: Bearer token with string context
22+
// Use a simple string identifier when your policy references a single context value.
2023
try {
21-
// Replace <YOUR_CREDENTIALS_FILE_PATH> with the full path to your credentials.json file
2224
String filePath = "<YOUR_CREDENTIALS_FILE_PATH>";
23-
24-
// Create a BearerToken object using the file path
2525
BearerToken token = BearerToken.builder()
26-
.setCredentials(new File(filePath)) // Set credentials using a File object
27-
.setCtx("abc") // Set context string (example: "abc")
28-
.build(); // Build the BearerToken object
26+
.setCredentials(new File(filePath))
27+
.setCtx("user_12345")
28+
.build();
2929

30-
// Retrieve the Bearer Token as a string
3130
bearerToken = token.getBearerToken();
32-
33-
// Print the generated Bearer Token to the console
34-
System.out.println(bearerToken);
31+
System.out.println("Bearer token (string context): " + bearerToken);
3532
} catch (SkyflowException e) {
36-
// Handle exceptions specific to Skyflow operations
3733
e.printStackTrace();
3834
}
3935

40-
// Approach 2: Generate Bearer Token by specifying the contents of credentials.json as a string
36+
// Approach 2: Bearer token with JSON object context
37+
// Use a structured Map when your policy needs multiple context values.
38+
// Each key maps to a Skyflow CEL policy variable under request.context.*
39+
// For example, the map below enables policies like:
40+
// request.context.role == "admin" && request.context.department == "finance"
4141
try {
42-
// Replace <YOUR_CREDENTIALS_FILE_CONTENTS_AS_STRING> with the actual contents of your credentials.json file
43-
String fileContents = "<YOUR_CREDENTIALS_FILE_CONTENTS_AS_STRING>";
42+
String filePath = "<YOUR_CREDENTIALS_FILE_PATH>";
43+
Map<String, Object> ctx = new HashMap<>();
44+
ctx.put("role", "admin");
45+
ctx.put("department", "finance");
46+
ctx.put("user_id", "user_12345");
4447

45-
// Create a BearerToken object using the file contents as a string
4648
BearerToken token = BearerToken.builder()
47-
.setCredentials(fileContents) // Set credentials using a string representation of the file
48-
.setCtx("abc") // Set context string (example: "abc")
49-
.build(); // Build the BearerToken object
49+
.setCredentials(new File(filePath))
50+
.setCtx(ctx)
51+
.build();
5052

51-
// Retrieve the Bearer Token as a string
5253
bearerToken = token.getBearerToken();
54+
System.out.println("Bearer token (object context): " + bearerToken);
55+
} catch (SkyflowException e) {
56+
e.printStackTrace();
57+
}
58+
59+
// Approach 3: Bearer token with string context from credentials string
60+
try {
61+
String fileContents = "<YOUR_CREDENTIALS_FILE_CONTENTS_AS_STRING>";
62+
BearerToken token = BearerToken.builder()
63+
.setCredentials(fileContents)
64+
.setCtx("user_12345")
65+
.build();
5366

54-
// Print the generated Bearer Token to the console
55-
System.out.println(bearerToken);
67+
bearerToken = token.getBearerToken();
68+
System.out.println("Bearer token (creds string): " + bearerToken);
5669
} catch (SkyflowException e) {
57-
// Handle exceptions specific to Skyflow operations
5870
e.printStackTrace();
5971
}
6072
}

0 commit comments

Comments
 (0)