Skip to content
Open
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
184 changes: 83 additions & 101 deletions docs/sdks/authorization.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -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:
<Tabs>
<TabItem value="go" label="Go">

| Helper | Description |
|--------|-------------|
Expand All @@ -88,7 +89,27 @@ req := &authorizationv2.GetDecisionRequest{
}
```

**Java** — build the nested proto structure:
</TabItem>
<TabItem value="java" label="Java">

| 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();
```

<details>
<summary>Without helpers (manual proto construction)</summary>

```java
EntityIdentifier.newBuilder()
Expand All @@ -103,7 +124,30 @@ EntityIdentifier.newBuilder()
.build()
```

**JavaScript** — use the `identifier` oneof:
</details>

</TabItem>
<TabItem value="js" label="JavaScript">

| 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'),
// ...
});
```

<details>
<summary>Without helpers (manual object construction)</summary>

```typescript
{
Expand All @@ -126,16 +170,22 @@ EntityIdentifier.newBuilder()
}
```

</details>

</TabItem>
</Tabs>

**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.
Expand Down Expand Up @@ -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**
Expand Down Expand Up @@ -279,18 +329,10 @@ for _, dr := range decisionResponse.GetDecisionResponses() {
<TabItem value="java" label="Java">

```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()
Expand All @@ -308,23 +350,10 @@ for (EntityEntitlements entitlement : resp.getEntitlementsList()) {
<TabItem value="js" label="JavaScript">

```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) {
Expand All @@ -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,
});

Expand Down Expand Up @@ -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. |

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

```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")
Expand Down Expand Up @@ -580,22 +591,11 @@ if (decision.getDecision() == Decision.DECISION_PERMIT) {
<TabItem value="js" label="JavaScript">

```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: {
Expand Down Expand Up @@ -778,20 +778,12 @@ for _, dr := range decisionResponse.GetDecisionResponses() {
<TabItem value="java" label="Java">

```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()
Expand Down Expand Up @@ -841,22 +833,12 @@ import GetDecisionsExample from '@site/code_samples/java/get-decisions.mdx';
<TabItem value="js" label="JavaScript">

```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: [
{
Expand Down
25 changes: 6 additions & 19 deletions docs/sdks/discovery.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -582,40 +582,27 @@ Entity.newBuilder().setId("e1").setUuid("550e8400-e29b-41d4-a716-446655440000").
<TabItem value="js" label="JavaScript">

```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) {
console.log("alice's entitlements:", resp.entitlements[0].actionsPerAttributeValueFqn);
}
```

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)
```

</TabItem>
Expand Down
Loading