Skip to content

Commit a8d4f50

Browse files
marythoughtclaude
andauthored
chore(docs): update Java/JS examples to use EntityIdentifier helpers (#291)
## Summary - Add `EntityIdentifiers` helper tables and examples for Java and JavaScript to the EntityIdentifier reference section (now in language tabs) - Update all Java examples to use `EntityIdentifiers.forEmail(...)` instead of verbose `EntityIdentifier.newBuilder().setEntityChain(...)` construction - Update all JavaScript examples to use `EntityIdentifiers.forEmail(...)` instead of verbose nested object literals - Update discovery page JS example to use helpers - Move verbose construction patterns to collapsible `<details>` blocks for reference ## Related - opentdf/web-sdk#916 — namespaces JS helpers under `EntityIdentifiers` (deprecates opentdf/web-sdk#911) - opentdf/java-sdk#346 — Java `EntityIdentifiers` convenience constructors - opentdf/platform#3232 — Go `EntityIdentifier` helpers ## Test plan - [x] Verify docs build (`npm run build`) passes - [ ] Check surge preview for correct rendering of helper tables, code examples, and details blocks 🤖 Generated with [Claude Code](https://claude.com/claude-code) <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Documentation** * Unified entity identification docs into language-specific tabs with examples for Go/Java/JavaScript * Replaced manual nested identifier examples with SDK helper-based examples across Java and JavaScript; simplified sample payloads for entitlements and decision requests * Added JavaScript support for request-token identifiers; clarified when manual construction (e.g., UUIDs) is still required * Linked discovery guide examples to the new helper-based guidance <!-- end of auto-generated comment: release notes by coderabbit.ai --> --------- Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent 60c73cd commit a8d4f50

2 files changed

Lines changed: 93 additions & 120 deletions

File tree

docs/sdks/authorization.mdx

Lines changed: 83 additions & 101 deletions
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,8 @@ const platformClient = new PlatformClient({
6969

7070
Every authorization call requires an `EntityIdentifier` — the entity (user, service, etc.) you're asking about. The entity can be identified by email, username, client ID, JWT token, claims, or registered resource FQN.
7171

72-
**Go** — use the v2 helper functions:
72+
<Tabs>
73+
<TabItem value="go" label="Go">
7374

7475
| Helper | Description |
7576
|--------|-------------|
@@ -88,7 +89,27 @@ req := &authorizationv2.GetDecisionRequest{
8889
}
8990
```
9091

91-
**Java** — build the nested proto structure:
92+
</TabItem>
93+
<TabItem value="java" label="Java">
94+
95+
| Helper | Description |
96+
|--------|-------------|
97+
| `EntityIdentifiers.forEmail(email)` | Identify by email address |
98+
| `EntityIdentifiers.forClientId(clientId)` | Identify by client ID (service account / NPE) |
99+
| `EntityIdentifiers.forUserName(username)` | Identify by username |
100+
| `EntityIdentifiers.forToken(jwt)` | Resolve entity from a JWT token |
101+
102+
```java
103+
import io.opentdf.platform.sdk.EntityIdentifiers;
104+
105+
GetDecisionRequest request = GetDecisionRequest.newBuilder()
106+
.setEntityIdentifier(EntityIdentifiers.forEmail("alice@example.com"))
107+
// ...
108+
.build();
109+
```
110+
111+
<details>
112+
<summary>Without helpers (manual proto construction)</summary>
92113

93114
```java
94115
EntityIdentifier.newBuilder()
@@ -103,7 +124,30 @@ EntityIdentifier.newBuilder()
103124
.build()
104125
```
105126

106-
**JavaScript** — use the `identifier` oneof:
127+
</details>
128+
129+
</TabItem>
130+
<TabItem value="js" label="JavaScript">
131+
132+
| Helper | Description |
133+
|--------|-------------|
134+
| `EntityIdentifiers.forEmail(email)` | Identify by email address |
135+
| `EntityIdentifiers.forClientId(clientId)` | Identify by client ID (service account / NPE) |
136+
| `EntityIdentifiers.forUserName(username)` | Identify by username |
137+
| `EntityIdentifiers.forToken(jwt)` | Resolve entity from a JWT token |
138+
| `EntityIdentifiers.withRequestToken()` | Derive entity from the request's Authorization header |
139+
140+
```typescript
141+
import { EntityIdentifiers } from '@opentdf/sdk';
142+
143+
const response = await platformClient.v2.authorization.getDecision({
144+
entityIdentifier: EntityIdentifiers.forEmail('alice@example.com'),
145+
// ...
146+
});
147+
```
148+
149+
<details>
150+
<summary>Without helpers (manual object construction)</summary>
107151

108152
```typescript
109153
{
@@ -126,16 +170,22 @@ EntityIdentifier.newBuilder()
126170
}
127171
```
128172

173+
</details>
174+
175+
</TabItem>
176+
</Tabs>
177+
129178
**Supported entity types:**
130179

131-
| Type | Go helper | Java setter | JS `case` |
132-
|------|-----------|-------------|-----------|
133-
| Email | `ForEmail(email)` | `.setEmailAddress(email)` | `'emailAddress'` |
134-
| Client ID | `ForClientID(id)` | `.setClientId(id)` | `'clientId'` |
135-
| Username | `ForUserName(name)` | `.setUserName(name)` | `'userName'` |
136-
| JWT Token | `ForToken(jwt)` | `.setToken(Token.newBuilder().setJwt(jwt))` | `'token'` |
137-
| Claims || `.setClaims(claims)` | `'claims'` |
138-
| Registered Resource || `.setRegisteredResourceValueFqn(fqn)` | `'registeredResourceValueFqn'` |
180+
| Type | Go | Java | JavaScript |
181+
|------|-----|------|------------|
182+
| Email | `ForEmail(email)` | `EntityIdentifiers.forEmail(email)` | `EntityIdentifiers.forEmail(email)` |
183+
| Client ID | `ForClientID(id)` | `EntityIdentifiers.forClientId(id)` | `EntityIdentifiers.forClientId(id)` |
184+
| Username | `ForUserName(name)` | `EntityIdentifiers.forUserName(name)` | `EntityIdentifiers.forUserName(name)` |
185+
| JWT Token | `ForToken(jwt)` | `EntityIdentifiers.forToken(jwt)` | `EntityIdentifiers.forToken(jwt)` |
186+
| Request Token | `WithRequestToken()` || `EntityIdentifiers.withRequestToken()` |
187+
| Claims || manual proto construction | manual object construction |
188+
| Registered Resource || manual proto construction | manual object construction |
139189

140190
- **Claims** are used by the Entity Resolution Service (ERS) for custom claim-based entity resolution.
141191
- **Registered Resource** identifies an entity by a [registered resource](/components/policy/registered_resources) value FQN stored in platform policy, where the resource acts as a single entity for authorization decisions.
@@ -176,7 +226,7 @@ await platformClient.v2.authorization.getEntitlements({ ... })
176226

177227
| Parameter | Type | Required | Description |
178228
|-----------|------|----------|-------------|
179-
| `entityIdentifier` | `EntityIdentifier` | Yes | The entity to query. In Go, use helpers like `authorizationv2.ForEmail("user@example.com")`. |
229+
| `entityIdentifier` | `EntityIdentifier` | Yes | The entity to query. Use [helpers](#entityidentifier) like `ForEmail(...)` (Go) or `EntityIdentifiers.forEmail(...)` (Java/JS). |
180230
| `withComprehensiveHierarchy` | `bool` | No | When true, returns all entitled values for attributes with hierarchy rules, propagating down from the entitled value. |
181231

182232
**Example**
@@ -279,18 +329,10 @@ for _, dr := range decisionResponse.GetDecisionResponses() {
279329
<TabItem value="java" label="Java">
280330

281331
```java
332+
import io.opentdf.platform.sdk.EntityIdentifiers;
333+
282334
GetEntitlementsRequest request = GetEntitlementsRequest.newBuilder()
283-
.setEntityIdentifier(
284-
EntityIdentifier.newBuilder()
285-
.setEntityChain(
286-
EntityChain.newBuilder()
287-
.addEntities(
288-
Entity.newBuilder()
289-
.setId("user-bob")
290-
.setEmailAddress("bob@OrgA.com")
291-
)
292-
)
293-
)
335+
.setEntityIdentifier(EntityIdentifiers.forEmail("bob@OrgA.com"))
294336
.build();
295337

296338
GetEntitlementsResponse resp = sdk.getServices()
@@ -308,23 +350,10 @@ for (EntityEntitlements entitlement : resp.getEntitlementsList()) {
308350
<TabItem value="js" label="JavaScript">
309351

310352
```typescript
353+
import { EntityIdentifiers } from '@opentdf/sdk';
354+
311355
const response = await platformClient.v2.authorization.getEntitlements({
312-
entityIdentifier: {
313-
identifier: {
314-
case: 'entityChain',
315-
value: {
316-
entities: [
317-
{
318-
ephemeralId: 'user-bob',
319-
entityType: {
320-
case: 'emailAddress',
321-
value: 'bob@OrgA.com',
322-
},
323-
},
324-
],
325-
},
326-
},
327-
},
356+
entityIdentifier: EntityIdentifiers.forEmail('bob@OrgA.com'),
328357
});
329358

330359
for (const entitlement of response.entitlements) {
@@ -335,20 +364,10 @@ for (const entitlement of response.entitlements) {
335364
To expand hierarchy rules:
336365

337366
```typescript
367+
import { EntityIdentifiers } from '@opentdf/sdk';
368+
338369
const response = await platformClient.v2.authorization.getEntitlements({
339-
entityIdentifier: {
340-
identifier: {
341-
case: 'entityChain',
342-
value: {
343-
entities: [
344-
{
345-
ephemeralId: 'user-123',
346-
entityType: { case: 'emailAddress', value: 'user@company.com' },
347-
},
348-
],
349-
},
350-
},
351-
},
370+
entityIdentifier: EntityIdentifiers.forEmail('user@company.com'),
352371
withComprehensiveHierarchy: true,
353372
});
354373

@@ -398,7 +417,7 @@ await platformClient.v2.authorization.getDecision({ ... })
398417

399418
| Parameter | Type | Required | Description |
400419
|-----------|------|----------|-------------|
401-
| `entityIdentifier` | `EntityIdentifier` | Yes | The entity requesting access. In Go, use helpers like `authorizationv2.ForEmail(...)` or `authorizationv2.ForToken(jwt)`. |
420+
| `entityIdentifier` | `EntityIdentifier` | Yes | The entity requesting access. Use [helpers](#entityidentifier) like `ForEmail(...)` (Go) or `EntityIdentifiers.forEmail(...)` (Java/JS). |
402421
| `action` | `Action` | Yes | The action being performed (e.g., `decrypt`, `read`). |
403422
| `resource` | `Resource` | Yes | The resource being accessed, identified by attribute value FQNs. |
404423

@@ -534,18 +553,10 @@ for _, dr := range decisionResponse.GetDecisionResponses() {
534553
<TabItem value="java" label="Java">
535554

536555
```java
556+
import io.opentdf.platform.sdk.EntityIdentifiers;
557+
537558
GetDecisionRequest request = GetDecisionRequest.newBuilder()
538-
.setEntityIdentifier(
539-
EntityIdentifier.newBuilder()
540-
.setEntityChain(
541-
EntityChain.newBuilder()
542-
.addEntities(
543-
Entity.newBuilder()
544-
.setId("user-123")
545-
.setEmailAddress("user@company.com")
546-
)
547-
)
548-
)
559+
.setEntityIdentifier(EntityIdentifiers.forEmail("user@company.com"))
549560
.setAction(
550561
Action.newBuilder()
551562
.setName("decrypt")
@@ -580,22 +591,11 @@ if (decision.getDecision() == Decision.DECISION_PERMIT) {
580591
<TabItem value="js" label="JavaScript">
581592

582593
```typescript
594+
import { EntityIdentifiers } from '@opentdf/sdk';
583595
import { Decision } from '@opentdf/sdk/platform/authorization/v2/authorization_pb.js';
584596

585597
const response = await platformClient.v2.authorization.getDecision({
586-
entityIdentifier: {
587-
identifier: {
588-
case: 'entityChain',
589-
value: {
590-
entities: [
591-
{
592-
ephemeralId: 'user-123',
593-
entityType: { case: 'emailAddress', value: 'user@company.com' },
594-
},
595-
],
596-
},
597-
},
598-
},
598+
entityIdentifier: EntityIdentifiers.forEmail('user@company.com'),
599599
action: { name: 'decrypt' },
600600
resource: {
601601
resource: {
@@ -778,20 +778,12 @@ for _, dr := range decisionResponse.GetDecisionResponses() {
778778
<TabItem value="java" label="Java">
779779

780780
```java
781+
import io.opentdf.platform.sdk.EntityIdentifiers;
782+
781783
GetDecisionBulkRequest request = GetDecisionBulkRequest.newBuilder()
782784
.addDecisionRequests(
783785
GetDecisionMultiResourceRequest.newBuilder()
784-
.setEntityIdentifier(
785-
EntityIdentifier.newBuilder()
786-
.setEntityChain(
787-
EntityChain.newBuilder()
788-
.addEntities(
789-
Entity.newBuilder()
790-
.setId("user-123")
791-
.setEmailAddress("user@company.com")
792-
)
793-
)
794-
)
786+
.setEntityIdentifier(EntityIdentifiers.forEmail("user@company.com"))
795787
.setAction(Action.newBuilder().setName("decrypt"))
796788
.addResources(
797789
Resource.newBuilder()
@@ -841,22 +833,12 @@ import GetDecisionsExample from '@site/code_samples/java/get-decisions.mdx';
841833
<TabItem value="js" label="JavaScript">
842834

843835
```typescript
836+
import { EntityIdentifiers } from '@opentdf/sdk';
837+
844838
const response = await platformClient.v2.authorization.getDecisionBulk({
845839
decisionRequests: [
846840
{
847-
entityIdentifier: {
848-
identifier: {
849-
case: 'entityChain',
850-
value: {
851-
entities: [
852-
{
853-
ephemeralId: 'user-123',
854-
entityType: { case: 'emailAddress', value: 'user@company.com' },
855-
},
856-
],
857-
},
858-
},
859-
},
841+
entityIdentifier: EntityIdentifiers.forEmail('user@company.com'),
860842
action: { name: 'decrypt' },
861843
resources: [
862844
{

docs/sdks/discovery.mdx

Lines changed: 10 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -582,42 +582,33 @@ Entity.newBuilder().setId("e1").setUuid("550e8400-e29b-41d4-a716-446655440000").
582582
<TabItem value="js" label="JavaScript">
583583
584584
```typescript
585+
import { EntityIdentifiers } from '@opentdf/sdk';
585586
import { PlatformClient } from '@opentdf/sdk/platform';
586587

587588
const platform = new PlatformClient({ ...auth, platformUrl });
588589

589590
const resp = await platform.v2.authorization.getEntitlements({
590-
entityIdentifier: {
591-
identifier: {
592-
case: 'entityChain',
593-
value: {
594-
ephemeralId: 'e1',
595-
entities: [
596-
{
597-
ephemeralId: 'e1',
598-
entityType: { case: 'emailAddress', value: 'alice@example.com' },
599-
},
600-
],
601-
},
602-
},
603-
},
591+
entityIdentifier: EntityIdentifiers.forEmail('alice@example.com'),
604592
});
605593

606594
if (resp.entitlements.length > 0) {
607595
console.log("alice's entitlements:", resp.entitlements[0].actionsPerAttributeValueFqn);
608596
}
609597
```
610598

611-
Other supported entity types (placed inside the `entities` array):
599+
Other supported [entity identifier helpers](/sdks/authorization#entityidentifier):
612600

613601
```typescript
614-
// By username
615-
{ ephemeralId: 'e1', entityType: { case: 'userName', value: 'alice' } }
602+
import { EntityIdentifiers } from '@opentdf/sdk';
616603

617-
// By client ID (NPE / service account)
618-
{ ephemeralId: 'e1', entityType: { case: 'clientId', value: 'my-service' } }
604+
EntityIdentifiers.forUserName('alice') // By username
605+
EntityIdentifiers.forClientId('my-service') // By client ID (NPE / service account)
619606
```
620607

608+
:::note
609+
The JavaScript SDK does not currently provide a `forUuid` helper. To use UUID-based entity identifiers, construct the `EntityIdentifier` manually using the protobuf message types from `@opentdf/sdk/platform`.
610+
:::
611+
621612
</TabItem>
622613
</Tabs>
623614

0 commit comments

Comments
 (0)