diff --git a/docs/sdks/authorization.mdx b/docs/sdks/authorization.mdx
index c97ddaef..da56c633 100644
--- a/docs/sdks/authorization.mdx
+++ b/docs/sdks/authorization.mdx
@@ -69,7 +69,8 @@ const platformClient = new PlatformClient({
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.
-**Go** — use the v2 helper functions:
+
+
| Helper | Description |
|--------|-------------|
@@ -88,7 +89,27 @@ req := &authorizationv2.GetDecisionRequest{
}
```
-**Java** — build the nested proto structure:
+
+
+
+| Helper | Description |
+|--------|-------------|
+| `EntityIdentifiers.forEmail(email)` | Identify by email address |
+| `EntityIdentifiers.forClientId(clientId)` | Identify by client ID (service account / NPE) |
+| `EntityIdentifiers.forUserName(username)` | Identify by username |
+| `EntityIdentifiers.forToken(jwt)` | Resolve entity from a JWT token |
+
+```java
+import io.opentdf.platform.sdk.EntityIdentifiers;
+
+GetDecisionRequest request = GetDecisionRequest.newBuilder()
+ .setEntityIdentifier(EntityIdentifiers.forEmail("alice@example.com"))
+ // ...
+ .build();
+```
+
+
+Without helpers (manual proto construction)
```java
EntityIdentifier.newBuilder()
@@ -103,7 +124,30 @@ EntityIdentifier.newBuilder()
.build()
```
-**JavaScript** — use the `identifier` oneof:
+
+
+
+
+
+| Helper | Description |
+|--------|-------------|
+| `EntityIdentifiers.forEmail(email)` | Identify by email address |
+| `EntityIdentifiers.forClientId(clientId)` | Identify by client ID (service account / NPE) |
+| `EntityIdentifiers.forUserName(username)` | Identify by username |
+| `EntityIdentifiers.forToken(jwt)` | Resolve entity from a JWT token |
+| `EntityIdentifiers.withRequestToken()` | Derive entity from the request's Authorization header |
+
+```typescript
+import { EntityIdentifiers } from '@opentdf/sdk';
+
+const response = await platformClient.v2.authorization.getDecision({
+ entityIdentifier: EntityIdentifiers.forEmail('alice@example.com'),
+ // ...
+});
+```
+
+
+Without helpers (manual object construction)
```typescript
{
@@ -126,16 +170,22 @@ EntityIdentifier.newBuilder()
}
```
+
+
+
+
+
**Supported entity types:**
-| Type | Go helper | Java setter | JS `case` |
-|------|-----------|-------------|-----------|
-| Email | `ForEmail(email)` | `.setEmailAddress(email)` | `'emailAddress'` |
-| Client ID | `ForClientID(id)` | `.setClientId(id)` | `'clientId'` |
-| Username | `ForUserName(name)` | `.setUserName(name)` | `'userName'` |
-| JWT Token | `ForToken(jwt)` | `.setToken(Token.newBuilder().setJwt(jwt))` | `'token'` |
-| Claims | — | `.setClaims(claims)` | `'claims'` |
-| Registered Resource | — | `.setRegisteredResourceValueFqn(fqn)` | `'registeredResourceValueFqn'` |
+| Type | Go | Java | JavaScript |
+|------|-----|------|------------|
+| Email | `ForEmail(email)` | `EntityIdentifiers.forEmail(email)` | `EntityIdentifiers.forEmail(email)` |
+| Client ID | `ForClientID(id)` | `EntityIdentifiers.forClientId(id)` | `EntityIdentifiers.forClientId(id)` |
+| Username | `ForUserName(name)` | `EntityIdentifiers.forUserName(name)` | `EntityIdentifiers.forUserName(name)` |
+| JWT Token | `ForToken(jwt)` | `EntityIdentifiers.forToken(jwt)` | `EntityIdentifiers.forToken(jwt)` |
+| Request Token | `WithRequestToken()` | — | `EntityIdentifiers.withRequestToken()` |
+| Claims | — | manual proto construction | manual object construction |
+| Registered Resource | — | manual proto construction | manual object construction |
- **Claims** are used by the Entity Resolution Service (ERS) for custom claim-based entity resolution.
- **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({ ... })
| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
-| `entityIdentifier` | `EntityIdentifier` | Yes | The entity to query. In Go, use helpers like `authorizationv2.ForEmail("user@example.com")`. |
+| `entityIdentifier` | `EntityIdentifier` | Yes | The entity to query. Use [helpers](#entityidentifier) like `ForEmail(...)` (Go), `EntityIdentifiers.forEmail(...)` (Java), or `EntityIdentifiers.forEmail(...)` (JS). |
| `withComprehensiveHierarchy` | `bool` | No | When true, returns all entitled values for attributes with hierarchy rules, propagating down from the entitled value. |
**Example**
@@ -279,18 +329,10 @@ for _, dr := range decisionResponse.GetDecisionResponses() {
```java
+import io.opentdf.platform.sdk.EntityIdentifiers;
+
GetEntitlementsRequest request = GetEntitlementsRequest.newBuilder()
- .setEntityIdentifier(
- EntityIdentifier.newBuilder()
- .setEntityChain(
- EntityChain.newBuilder()
- .addEntities(
- Entity.newBuilder()
- .setId("user-bob")
- .setEmailAddress("bob@OrgA.com")
- )
- )
- )
+ .setEntityIdentifier(EntityIdentifiers.forEmail("bob@OrgA.com"))
.build();
GetEntitlementsResponse resp = sdk.getServices()
@@ -308,23 +350,10 @@ for (EntityEntitlements entitlement : resp.getEntitlementsList()) {
```typescript
+import { EntityIdentifiers } from '@opentdf/sdk';
+
const response = await platformClient.v2.authorization.getEntitlements({
- entityIdentifier: {
- identifier: {
- case: 'entityChain',
- value: {
- entities: [
- {
- ephemeralId: 'user-bob',
- entityType: {
- case: 'emailAddress',
- value: 'bob@OrgA.com',
- },
- },
- ],
- },
- },
- },
+ entityIdentifier: EntityIdentifiers.forEmail('bob@OrgA.com'),
});
for (const entitlement of response.entitlements) {
@@ -335,20 +364,10 @@ for (const entitlement of response.entitlements) {
To expand hierarchy rules:
```typescript
+import { EntityIdentifiers } from '@opentdf/sdk';
+
const response = await platformClient.v2.authorization.getEntitlements({
- entityIdentifier: {
- identifier: {
- case: 'entityChain',
- value: {
- entities: [
- {
- ephemeralId: 'user-123',
- entityType: { case: 'emailAddress', value: 'user@company.com' },
- },
- ],
- },
- },
- },
+ entityIdentifier: EntityIdentifiers.forEmail('user@company.com'),
withComprehensiveHierarchy: true,
});
@@ -398,7 +417,7 @@ await platformClient.v2.authorization.getDecision({ ... })
| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
-| `entityIdentifier` | `EntityIdentifier` | Yes | The entity requesting access. In Go, use helpers like `authorizationv2.ForEmail(...)` or `authorizationv2.ForToken(jwt)`. |
+| `entityIdentifier` | `EntityIdentifier` | Yes | The entity requesting access. Use [helpers](#entityidentifier) like `ForEmail(...)` (Go), `EntityIdentifiers.forEmail(...)` (Java), or `EntityIdentifiers.forEmail(...)` (JS). |
| `action` | `Action` | Yes | The action being performed (e.g., `decrypt`, `read`). |
| `resource` | `Resource` | Yes | The resource being accessed, identified by attribute value FQNs. |
@@ -534,18 +553,10 @@ for _, dr := range decisionResponse.GetDecisionResponses() {
```java
+import io.opentdf.platform.sdk.EntityIdentifiers;
+
GetDecisionRequest request = GetDecisionRequest.newBuilder()
- .setEntityIdentifier(
- EntityIdentifier.newBuilder()
- .setEntityChain(
- EntityChain.newBuilder()
- .addEntities(
- Entity.newBuilder()
- .setId("user-123")
- .setEmailAddress("user@company.com")
- )
- )
- )
+ .setEntityIdentifier(EntityIdentifiers.forEmail("user@company.com"))
.setAction(
Action.newBuilder()
.setName("decrypt")
@@ -580,22 +591,11 @@ if (decision.getDecision() == Decision.DECISION_PERMIT) {
```typescript
+import { EntityIdentifiers } from '@opentdf/sdk';
import { Decision } from '@opentdf/sdk/platform/authorization/v2/authorization_pb.js';
const response = await platformClient.v2.authorization.getDecision({
- entityIdentifier: {
- identifier: {
- case: 'entityChain',
- value: {
- entities: [
- {
- ephemeralId: 'user-123',
- entityType: { case: 'emailAddress', value: 'user@company.com' },
- },
- ],
- },
- },
- },
+ entityIdentifier: EntityIdentifiers.forEmail('user@company.com'),
action: { name: 'decrypt' },
resource: {
resource: {
@@ -778,20 +778,12 @@ for _, dr := range decisionResponse.GetDecisionResponses() {
```java
+import io.opentdf.platform.sdk.EntityIdentifiers;
+
GetDecisionBulkRequest request = GetDecisionBulkRequest.newBuilder()
.addDecisionRequests(
GetDecisionMultiResourceRequest.newBuilder()
- .setEntityIdentifier(
- EntityIdentifier.newBuilder()
- .setEntityChain(
- EntityChain.newBuilder()
- .addEntities(
- Entity.newBuilder()
- .setId("user-123")
- .setEmailAddress("user@company.com")
- )
- )
- )
+ .setEntityIdentifier(EntityIdentifiers.forEmail("user@company.com"))
.setAction(Action.newBuilder().setName("decrypt"))
.addResources(
Resource.newBuilder()
@@ -841,22 +833,12 @@ import GetDecisionsExample from '@site/code_samples/java/get-decisions.mdx';
```typescript
+import { EntityIdentifiers } from '@opentdf/sdk';
+
const response = await platformClient.v2.authorization.getDecisionBulk({
decisionRequests: [
{
- entityIdentifier: {
- identifier: {
- case: 'entityChain',
- value: {
- entities: [
- {
- ephemeralId: 'user-123',
- entityType: { case: 'emailAddress', value: 'user@company.com' },
- },
- ],
- },
- },
- },
+ entityIdentifier: EntityIdentifiers.forEmail('user@company.com'),
action: { name: 'decrypt' },
resources: [
{
diff --git a/docs/sdks/discovery.mdx b/docs/sdks/discovery.mdx
index 04ba3ba3..a286729f 100644
--- a/docs/sdks/discovery.mdx
+++ b/docs/sdks/discovery.mdx
@@ -582,25 +582,13 @@ Entity.newBuilder().setId("e1").setUuid("550e8400-e29b-41d4-a716-446655440000").
```typescript
+import { EntityIdentifiers } from '@opentdf/sdk';
import { PlatformClient } from '@opentdf/sdk/platform';
const platform = new PlatformClient({ ...auth, platformUrl });
const resp = await platform.v2.authorization.getEntitlements({
- entityIdentifier: {
- identifier: {
- case: 'entityChain',
- value: {
- ephemeralId: 'e1',
- entities: [
- {
- ephemeralId: 'e1',
- entityType: { case: 'emailAddress', value: 'alice@example.com' },
- },
- ],
- },
- },
- },
+ entityIdentifier: EntityIdentifiers.forEmail('alice@example.com'),
});
if (resp.entitlements.length > 0) {
@@ -608,14 +596,13 @@ if (resp.entitlements.length > 0) {
}
```
-Other supported entity types (placed inside the `entities` array):
+Other supported [entity identifier helpers](/sdks/authorization#entityidentifier):
```typescript
-// By username
-{ ephemeralId: 'e1', entityType: { case: 'userName', value: 'alice' } }
+import { EntityIdentifiers } from '@opentdf/sdk';
-// By client ID (NPE / service account)
-{ ephemeralId: 'e1', entityType: { case: 'clientId', value: 'my-service' } }
+EntityIdentifiers.forUserName('alice') // By username
+EntityIdentifiers.forClientId('my-service') // By client ID (NPE / service account)
```