Skip to content

Commit 2374648

Browse files
marythoughtclaude
andcommitted
chore(docs): add Resource constructor helpers and update examples
Document the new Resource helper functions (ForAttributeValues, ForRegisteredResourceValueFqn) for Go, Java, and JavaScript SDKs. Update GetDecision examples to use the helpers instead of verbose manual proto construction. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> Signed-off-by: Mary Dickson <mary.dickson@virtru.com>
1 parent e7a40fc commit 2374648

1 file changed

Lines changed: 171 additions & 55 deletions

File tree

docs/sdks/authorization.mdx

Lines changed: 171 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -190,6 +190,134 @@ const response = await platformClient.v2.authorization.getDecision({
190190
- **Claims** are used by the Entity Resolution Service (ERS) for custom claim-based entity resolution.
191191
- **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.
192192

193+
### Resource
194+
195+
A `Resource` identifies the data being accessed in [GetDecision](#getdecision) and [GetDecisionBulk](#getdecisionbulk) calls. It can be specified as a set of attribute value FQNs (most common — e.g. the attributes on a TDF) or as a [registered resource](/components/policy/registered_resources) value FQN stored in platform policy.
196+
197+
<Tabs>
198+
<TabItem value="go" label="Go">
199+
200+
| Helper | Description |
201+
|--------|-------------|
202+
| `authorizationv2.ForAttributeValues(fqns...)` | Resource from attribute value FQNs (e.g. those on a TDF) |
203+
| `authorizationv2.ForRegisteredResourceValueFqn(fqn)` | Resource from a registered resource value FQN in policy |
204+
205+
```go
206+
import authorizationv2 "github.com/opentdf/platform/protocol/go/authorization/v2"
207+
208+
req := &authorizationv2.GetDecisionRequest{
209+
Resource: authorizationv2.ForAttributeValues(
210+
"https://example.com/attr/classification/value/confidential",
211+
"https://example.com/attr/department/value/finance",
212+
),
213+
// ...
214+
}
215+
```
216+
217+
<details>
218+
<summary>Without helpers (manual proto construction)</summary>
219+
220+
```go
221+
&authorizationv2.Resource{
222+
Resource: &authorizationv2.Resource_AttributeValues_{
223+
AttributeValues: &authorizationv2.Resource_AttributeValues{
224+
Fqns: []string{
225+
"https://example.com/attr/classification/value/confidential",
226+
"https://example.com/attr/department/value/finance",
227+
},
228+
},
229+
},
230+
}
231+
```
232+
233+
</details>
234+
235+
</TabItem>
236+
<TabItem value="java" label="Java">
237+
238+
| Helper | Description |
239+
|--------|-------------|
240+
| `Resources.forAttributeValues(fqns...)` | Resource from attribute value FQNs (e.g. those on a TDF) |
241+
| `Resources.forRegisteredResourceValueFqn(fqn)` | Resource from a registered resource value FQN in policy |
242+
243+
```java
244+
import io.opentdf.platform.sdk.Resources;
245+
246+
GetDecisionRequest request = GetDecisionRequest.newBuilder()
247+
.setResource(Resources.forAttributeValues(
248+
"https://example.com/attr/classification/value/confidential",
249+
"https://example.com/attr/department/value/finance"))
250+
// ...
251+
.build();
252+
```
253+
254+
<details>
255+
<summary>Without helpers (manual proto construction)</summary>
256+
257+
```java
258+
Resource.newBuilder()
259+
.setAttributeValues(
260+
Resource.AttributeValues.newBuilder()
261+
.addFqns("https://example.com/attr/classification/value/confidential")
262+
.addFqns("https://example.com/attr/department/value/finance"))
263+
.build()
264+
```
265+
266+
</details>
267+
268+
</TabItem>
269+
<TabItem value="js" label="JavaScript">
270+
271+
| Helper | Description |
272+
|--------|-------------|
273+
| `Resources.forAttributeValues(...fqns)` | Resource from attribute value FQNs (e.g. those on a TDF) |
274+
| `Resources.forRegisteredResourceValueFqn(fqn)` | Resource from a registered resource value FQN in policy |
275+
276+
```typescript
277+
import { Resources } from '@opentdf/sdk';
278+
279+
const response = await platformClient.v2.authorization.getDecision({
280+
resource: Resources.forAttributeValues(
281+
'https://example.com/attr/classification/value/confidential',
282+
'https://example.com/attr/department/value/finance',
283+
),
284+
// ...
285+
});
286+
```
287+
288+
<details>
289+
<summary>Without helpers (manual object construction)</summary>
290+
291+
```typescript
292+
{
293+
resource: {
294+
case: 'attributeValues',
295+
value: {
296+
fqns: [
297+
'https://example.com/attr/classification/value/confidential',
298+
'https://example.com/attr/department/value/finance',
299+
],
300+
},
301+
},
302+
}
303+
```
304+
305+
</details>
306+
307+
</TabItem>
308+
</Tabs>
309+
310+
**Resource variants:**
311+
312+
| Variant | Go | Java | JavaScript |
313+
|---------|-----|------|------------|
314+
| Attribute values | `ForAttributeValues(fqns...)` | `Resources.forAttributeValues(fqns...)` | `Resources.forAttributeValues(...fqns)` |
315+
| Registered resource | `ForRegisteredResourceValueFqn(fqn)` | `Resources.forRegisteredResourceValueFqn(fqn)` | `Resources.forRegisteredResourceValueFqn(fqn)` |
316+
317+
:::note
318+
The helpers do not set `ephemeralId`. For [GetDecisionBulk](#getdecisionbulk) where you need to correlate requests with responses, set `ephemeralId` separately after construction or use manual construction.
319+
:::
320+
193321
---
194322

195323
## GetEntitlements
@@ -419,7 +547,7 @@ await platformClient.v2.authorization.getDecision({ ... })
419547
|-----------|------|----------|-------------|
420548
| `entityIdentifier` | `EntityIdentifier` | Yes | The entity requesting access. Use [helpers](#entityidentifier) like `ForEmail(...)` (Go) or `EntityIdentifiers.forEmail(...)` (Java/JS). |
421549
| `action` | `Action` | Yes | The action being performed (e.g., `decrypt`, `read`). |
422-
| `resource` | `Resource` | Yes | The resource being accessed, identified by attribute value FQNs. |
550+
| `resource` | `Resource` | Yes | The resource being accessed. Use [helpers](#resource) like `ForAttributeValues(...)` (Go) or `Resources.forAttributeValues(...)` (Java/JS). |
423551

424552
**Example**
425553

@@ -437,16 +565,10 @@ decisionReq := &authorizationv2.GetDecisionRequest{
437565
Action: &policy.Action{
438566
Name: "decrypt",
439567
},
440-
Resource: &authorizationv2.Resource{
441-
Resource: &authorizationv2.Resource_AttributeValues_{
442-
AttributeValues: &authorizationv2.Resource_AttributeValues{
443-
Fqns: []string{
444-
"https://company.com/attr/clearance/value/confidential",
445-
"https://company.com/attr/department/value/finance",
446-
},
447-
},
448-
},
449-
},
568+
Resource: authorizationv2.ForAttributeValues(
569+
"https://company.com/attr/clearance/value/confidential",
570+
"https://company.com/attr/department/value/finance",
571+
),
450572
}
451573

452574
decision, err := client.AuthorizationV2.GetDecision(
@@ -479,13 +601,9 @@ import (
479601
decisionReq := &authorizationv2.GetDecisionRequest{
480602
EntityIdentifier: authorizationv2.ForToken(jwtToken),
481603
Action: &policy.Action{Name: "decrypt"},
482-
Resource: &authorizationv2.Resource{
483-
Resource: &authorizationv2.Resource_AttributeValues_{
484-
AttributeValues: &authorizationv2.Resource_AttributeValues{
485-
Fqns: []string{"https://company.com/attr/clearance/value/public"},
486-
},
487-
},
488-
},
604+
Resource: authorizationv2.ForAttributeValues(
605+
"https://company.com/attr/clearance/value/public",
606+
),
489607
}
490608

491609
decision, err := client.AuthorizationV2.GetDecision(
@@ -554,21 +672,17 @@ for _, dr := range decisionResponse.GetDecisionResponses() {
554672

555673
```java
556674
import io.opentdf.platform.sdk.EntityIdentifiers;
675+
import io.opentdf.platform.sdk.Resources;
557676

558677
GetDecisionRequest request = GetDecisionRequest.newBuilder()
559678
.setEntityIdentifier(EntityIdentifiers.forEmail("user@company.com"))
560679
.setAction(
561680
Action.newBuilder()
562681
.setName("decrypt")
563682
)
564-
.setResource(
565-
Resource.newBuilder()
566-
.setAttributeValues(
567-
Resource.AttributeValues.newBuilder()
568-
.addFqns("https://company.com/attr/clearance/value/confidential")
569-
.addFqns("https://company.com/attr/department/value/finance")
570-
)
571-
)
683+
.setResource(Resources.forAttributeValues(
684+
"https://company.com/attr/clearance/value/confidential",
685+
"https://company.com/attr/department/value/finance"))
572686
.build();
573687

574688
GetDecisionResponse resp = sdk.getServices()
@@ -591,23 +705,16 @@ if (decision.getDecision() == Decision.DECISION_PERMIT) {
591705
<TabItem value="js" label="JavaScript">
592706

593707
```typescript
594-
import { EntityIdentifiers } from '@opentdf/sdk';
708+
import { EntityIdentifiers, Resources } from '@opentdf/sdk';
595709
import { Decision } from '@opentdf/sdk/platform/authorization/v2/authorization_pb.js';
596710

597711
const response = await platformClient.v2.authorization.getDecision({
598712
entityIdentifier: EntityIdentifiers.forEmail('user@company.com'),
599713
action: { name: 'decrypt' },
600-
resource: {
601-
resource: {
602-
case: 'attributeValues',
603-
value: {
604-
fqns: [
605-
'https://company.com/attr/clearance/value/confidential',
606-
'https://company.com/attr/department/value/finance',
607-
],
608-
},
609-
},
610-
},
714+
resource: Resources.forAttributeValues(
715+
'https://company.com/attr/clearance/value/confidential',
716+
'https://company.com/attr/department/value/finance',
717+
),
611718
});
612719

613720
const decision = response.decision;
@@ -912,29 +1019,38 @@ Identifies the data being accessed. A resource can be specified in two ways:
9121019
| `attributeValues.fqns` | `[]string` | Attribute value FQNs on the resource (1–20). Use this for TDF payloads or any resource identified by attribute values. |
9131020
| `registeredResourceValueFqn` | `string` (URI) | A [registered resource](/components/policy/registered_resources) value FQN stored in platform policy. Alternative to `attributeValues`. |
9141021

1022+
Use the [Resource helpers](#resource) for concise construction:
1023+
1024+
<Tabs>
1025+
<TabItem value="go" label="Go">
1026+
9151027
```go
916-
// Go
917-
&authorizationv2.Resource{
918-
EphemeralId: "resource-1",
919-
Resource: &authorizationv2.Resource_AttributeValues_{
920-
AttributeValues: &authorizationv2.Resource_AttributeValues{
921-
Fqns: []string{"https://example.com/attr/classification/value/secret"},
922-
},
923-
},
924-
}
1028+
// With helpers
1029+
authorizationv2.ForAttributeValues("https://example.com/attr/classification/value/secret")
1030+
authorizationv2.ForRegisteredResourceValueFqn("https://example.com/registered/value/my-resource")
1031+
```
1032+
1033+
</TabItem>
1034+
<TabItem value="java" label="Java">
1035+
1036+
```java
1037+
// With helpers
1038+
Resources.forAttributeValues("https://example.com/attr/classification/value/secret")
1039+
Resources.forRegisteredResourceValueFqn("https://example.com/registered/value/my-resource")
9251040
```
9261041

1042+
</TabItem>
1043+
<TabItem value="js" label="JavaScript">
1044+
9271045
```typescript
928-
// JavaScript
929-
{
930-
ephemeralId: 'resource-1',
931-
resource: {
932-
case: 'attributeValues',
933-
value: { fqns: ['https://example.com/attr/classification/value/secret'] },
934-
},
935-
}
1046+
// With helpers
1047+
Resources.forAttributeValues('https://example.com/attr/classification/value/secret')
1048+
Resources.forRegisteredResourceValueFqn('https://example.com/registered/value/my-resource')
9361049
```
9371050

1051+
</TabItem>
1052+
</Tabs>
1053+
9381054
### EntityEntitlements
9391055

9401056
Returned by [GetEntitlements](#getentitlements). One per entity, mapping attribute value FQNs to the actions that entity can perform.

0 commit comments

Comments
 (0)