-
Notifications
You must be signed in to change notification settings - Fork 2
feat(docs): expand TDF documentation #225
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
marythought
wants to merge
18
commits into
main
Choose a base branch
from
docs/DSPX-2427-expand-tdf-documentation
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
+2,094
−20
Open
Changes from all commits
Commits
Show all changes
18 commits
Select commit
Hold shift + click to select a range
d8c8ddd
feat(docs): expand TDF documentation with full encrypt/decrypt options
marythought 757c398
Merge branch 'main' into docs/DSPX-2427-expand-tdf-documentation
marythought 3f138c0
Remove OpenTDF brand reference from tdf.mdx prose for DSP import
marythought a793b6f
Remove prerequisites callout; add intro to Basic Encrypt & Decrypt se…
marythought ff319f1
restructure TDF page as API reference with method signatures and para…
marythought 658e994
fix code review: remove unused open() call and define ctx in bulk dec…
marythought 4e4076c
add necessary imports to all Go, Java, and TypeScript code blocks
marythought 97e6a2f
add Manifest Object reference section with field tables and example
marythought 0bb1b9b
add KASInfo and PolicyObject type reference sections
marythought 4dbdff5
fix: add cross-reference links and fix anchor in tdf.mdx
marythought 20b549f
refactor: demote method sub-sections to bold labels in tdf.mdx
marythought 9fe3e0b
fix: use real angle brackets inside backtick spans in PolicyObject table
marythought 45ccf8e
docs: clarify wrapping key algorithm and session key type descriptions
marythought a40cebb
docs: replace classification/secret FQNs with clearance/executive acr…
marythought bb0a77e
Merge branch 'main' into docs/DSPX-2427-expand-tdf-documentation
marythought 16d814f
refactor: remove duplicate Reading the Decrypted Payload section
marythought 8121305
docs(tdf): address developer experience blockers
marythought 77052ab
docs(tdf): add page intro with section map and remove auth guide link
marythought File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,358 @@ | ||
| import Tabs from '@theme/Tabs'; | ||
| import TabItem from '@theme/TabItem'; | ||
|
|
||
| ## Decrypt Options | ||
|
|
||
| The following options can be passed to the decrypt call to control how the TDF is opened and validated. | ||
|
|
||
| --- | ||
|
|
||
| ### KAS Allowlist | ||
|
|
||
| Restrict decryption to only contact KAS endpoints on an explicit allowlist. If the TDF references a KAS not on the list, decryption will fail. This is a security control to prevent credential exfiltration to a rogue KAS. | ||
|
|
||
| <Tabs> | ||
| <TabItem value="go" label="Go"> | ||
|
|
||
| ```go | ||
| import ( | ||
| "bytes" | ||
|
|
||
| "github.com/opentdf/platform/sdk" | ||
| ) | ||
|
|
||
| tdfReader, err := client.LoadTDF( | ||
| bytes.NewReader(encryptedBytes), | ||
| sdk.WithKasAllowlist([]string{ | ||
| "https://kas.example.com", | ||
| "https://kas-backup.example.com", | ||
| }), | ||
| ) | ||
| ``` | ||
|
|
||
| </TabItem> | ||
| <TabItem value="java" label="Java"> | ||
|
|
||
| ```java | ||
| import io.opentdf.platform.sdk.Config; | ||
| import io.opentdf.platform.sdk.TDF; | ||
|
|
||
| Config.TDFReaderConfig readerConfig = Config.newTDFReaderConfig( | ||
| Config.WithKasAllowlist( | ||
| "https://kas.example.com", | ||
| "https://kas-backup.example.com" | ||
| ) | ||
| ); | ||
| TDF.Reader reader = sdk.loadTDF(fileChannel, readerConfig); | ||
| ``` | ||
|
|
||
| </TabItem> | ||
| <TabItem value="js" label="JavaScript"> | ||
|
|
||
| ```typescript | ||
| const plaintext = await client.read({ | ||
| source: { type: 'buffer', location: encryptedBytes }, | ||
| allowedKASEndpoints: [ | ||
| 'https://kas.example.com', | ||
| 'https://kas-backup.example.com', | ||
| ], | ||
| }); | ||
| ``` | ||
|
|
||
| </TabItem> | ||
| </Tabs> | ||
|
|
||
| --- | ||
|
|
||
| ### Ignore KAS Allowlist | ||
|
|
||
| Disable the KAS allowlist check entirely. The SDK will contact any KAS referenced in the TDF manifest without restriction. | ||
|
|
||
| :::warning Security consideration | ||
| Only use this in controlled environments (e.g., integration tests, airgapped deployments where all KAS endpoints are trusted). In production, the allowlist is an important defence against credential forwarding attacks. | ||
| ::: | ||
|
|
||
| <Tabs> | ||
| <TabItem value="go" label="Go"> | ||
|
|
||
| ```go | ||
| import ( | ||
| "bytes" | ||
|
|
||
| "github.com/opentdf/platform/sdk" | ||
| ) | ||
|
|
||
| tdfReader, err := client.LoadTDF( | ||
| bytes.NewReader(encryptedBytes), | ||
| sdk.WithIgnoreAllowlist(true), | ||
| ) | ||
| ``` | ||
|
|
||
| </TabItem> | ||
| <TabItem value="java" label="Java"> | ||
|
|
||
| ```java | ||
| import io.opentdf.platform.sdk.Config; | ||
| import io.opentdf.platform.sdk.TDF; | ||
|
|
||
| Config.TDFReaderConfig readerConfig = Config.newTDFReaderConfig( | ||
| Config.WithIgnoreKasAllowlist(true) | ||
| ); | ||
| TDF.Reader reader = sdk.loadTDF(fileChannel, readerConfig); | ||
| ``` | ||
|
|
||
| </TabItem> | ||
| <TabItem value="js" label="JavaScript"> | ||
|
|
||
| ```typescript | ||
| const plaintext = await client.read({ | ||
| source: { type: 'buffer', location: encryptedBytes }, | ||
| ignoreAllowlist: true, | ||
| }); | ||
| ``` | ||
|
|
||
| </TabItem> | ||
| </Tabs> | ||
|
|
||
| --- | ||
|
|
||
| ### Assertion Verification Keys | ||
|
|
||
| Provide public keys used to verify signed assertions embedded in the TDF. If an assertion was signed during encryption, you must supply the corresponding verification key here or verification will fail. | ||
|
|
||
| <Tabs> | ||
| <TabItem value="go" label="Go"> | ||
|
|
||
| ```go | ||
| import ( | ||
| "bytes" | ||
|
|
||
| "github.com/opentdf/platform/sdk" | ||
| ) | ||
|
|
||
| verificationKeys := sdk.AssertionVerificationKeys{ | ||
| Keys: map[string]sdk.AssertionKey{ | ||
| "assertion-1": { | ||
| Alg: sdk.AssertionKeyAlgRS256, | ||
| Key: rsaPublicKey, // *rsa.PublicKey | ||
| }, | ||
| }, | ||
| } | ||
|
|
||
| tdfReader, err := client.LoadTDF( | ||
| bytes.NewReader(encryptedBytes), | ||
| sdk.WithAssertionVerificationKeys(verificationKeys), | ||
| ) | ||
| ``` | ||
|
|
||
| </TabItem> | ||
| <TabItem value="java" label="Java"> | ||
|
|
||
| ```java | ||
| import io.opentdf.platform.sdk.AssertionConfig; | ||
| import io.opentdf.platform.sdk.Config; | ||
| import io.opentdf.platform.sdk.TDF; | ||
| import java.util.Map; | ||
|
|
||
| var assertionKey = new AssertionConfig.AssertionKey( | ||
| AssertionConfig.AssertionKeyAlg.RS256, | ||
| rsaPublicKey | ||
| ); | ||
|
|
||
| var verificationKeys = new Config.AssertionVerificationKeys(); | ||
| verificationKeys.keys = Map.of("assertion-1", assertionKey); | ||
|
|
||
| Config.TDFReaderConfig readerConfig = Config.newTDFReaderConfig( | ||
| Config.withAssertionVerificationKeys(verificationKeys) | ||
| ); | ||
| TDF.Reader reader = sdk.loadTDF(fileChannel, readerConfig); | ||
| ``` | ||
|
|
||
| </TabItem> | ||
| <TabItem value="js" label="JavaScript"> | ||
|
|
||
| ```typescript | ||
| const plaintext = await client.read({ | ||
| source: { type: 'buffer', location: encryptedBytes }, | ||
| assertionVerificationKeys: { | ||
| keys: { | ||
| 'assertion-1': { | ||
| alg: 'RS256', | ||
| key: rsaPublicKey, // CryptoKey | ||
| }, | ||
| }, | ||
| }, | ||
| }); | ||
| ``` | ||
|
|
||
| </TabItem> | ||
| </Tabs> | ||
|
|
||
| --- | ||
|
|
||
| ### Disable Assertion Verification | ||
|
|
||
| Skip cryptographic verification of all assertions in the TDF. The assertions will still be read and returned, but their signatures will not be checked. | ||
|
|
||
| :::warning | ||
| Disabling assertion verification removes a tamper-detection layer. Only use this when you have explicitly verified the TDF's integrity through another mechanism. | ||
| ::: | ||
|
|
||
| <Tabs> | ||
| <TabItem value="go" label="Go"> | ||
|
|
||
| ```go | ||
| import ( | ||
| "bytes" | ||
|
|
||
| "github.com/opentdf/platform/sdk" | ||
| ) | ||
|
|
||
| tdfReader, err := client.LoadTDF( | ||
| bytes.NewReader(encryptedBytes), | ||
| sdk.WithDisableAssertionVerification(true), | ||
| ) | ||
| ``` | ||
|
|
||
| </TabItem> | ||
| <TabItem value="java" label="Java"> | ||
|
|
||
| ```java | ||
| import io.opentdf.platform.sdk.Config; | ||
| import io.opentdf.platform.sdk.TDF; | ||
|
|
||
| Config.TDFReaderConfig readerConfig = Config.newTDFReaderConfig( | ||
| Config.withDisableAssertionVerification(true) | ||
| ); | ||
| TDF.Reader reader = sdk.loadTDF(fileChannel, readerConfig); | ||
| ``` | ||
|
|
||
| </TabItem> | ||
| <TabItem value="js" label="JavaScript"> | ||
|
|
||
| ```typescript | ||
| const plaintext = await client.read({ | ||
| source: { type: 'buffer', location: encryptedBytes }, | ||
| noVerify: true, | ||
| }); | ||
| ``` | ||
|
|
||
| </TabItem> | ||
| </Tabs> | ||
|
|
||
| --- | ||
|
|
||
| ### Session Key Type | ||
|
|
||
| During decryption, the SDK generates a short-lived (ephemeral) asymmetric key pair and sends the public half to the KAS. The KAS uses it to securely return the unwrapped Data Encryption Key back to the SDK. This option controls the algorithm used for that ephemeral key pair. | ||
|
|
||
| The default is `rsa:2048`. Use `ec:secp256r1` (or another EC variant) for smaller messages and faster key exchange. Must match an algorithm supported by the KAS. | ||
|
|
||
| <Tabs> | ||
| <TabItem value="go" label="Go"> | ||
|
|
||
| ```go | ||
| import ( | ||
| "bytes" | ||
|
|
||
| "github.com/opentdf/platform/lib/ocrypto" | ||
| "github.com/opentdf/platform/sdk" | ||
| ) | ||
|
|
||
| tdfReader, err := client.LoadTDF( | ||
| bytes.NewReader(encryptedBytes), | ||
| sdk.WithSessionKeyType(ocrypto.EC256Key), | ||
| ) | ||
| ``` | ||
|
|
||
| </TabItem> | ||
| <TabItem value="java" label="Java"> | ||
|
|
||
| ```java | ||
| import io.opentdf.platform.sdk.Config; | ||
| import io.opentdf.platform.sdk.TDF; | ||
|
|
||
| Config.TDFReaderConfig readerConfig = Config.newTDFReaderConfig( | ||
| Config.WithSessionKeyType(KeyType.EC256Key) | ||
| ); | ||
| TDF.Reader reader = sdk.loadTDF(fileChannel, readerConfig); | ||
| ``` | ||
|
|
||
| </TabItem> | ||
| <TabItem value="js" label="JavaScript"> | ||
|
|
||
| ```typescript | ||
| const plaintext = await client.read({ | ||
| source: { type: 'buffer', location: encryptedBytes }, | ||
| wrappingKeyAlgorithm: 'ec:secp256r1', | ||
| }); | ||
| ``` | ||
|
|
||
| </TabItem> | ||
| </Tabs> | ||
|
|
||
| --- | ||
|
|
||
| ### Fulfillable Obligations | ||
|
|
||
| Declare which obligation FQNs the calling application is prepared to fulfil. The platform may attach obligations to an access decision — if an obligation is not declared as fulfillable, decryption may be denied. | ||
|
|
||
| <Tabs> | ||
| <TabItem value="go" label="Go"> | ||
|
|
||
| ```go | ||
| import ( | ||
| "bytes" | ||
|
|
||
| "github.com/opentdf/platform/sdk" | ||
| ) | ||
|
|
||
| tdfReader, err := client.LoadTDF( | ||
| bytes.NewReader(encryptedBytes), | ||
| sdk.WithTDFFulfillableObligationFQNs([]string{ | ||
| "https://example.com/obl/audit/value/log", | ||
| "https://example.com/obl/watermark/value/apply", | ||
| }), | ||
| ) | ||
| ``` | ||
|
|
||
| </TabItem> | ||
| <TabItem value="java" label="Java"> | ||
|
|
||
| Fulfillable obligations are not yet supported in the Java SDK TDF reader config. Configure them at the SDK level via `SDKBuilder` if available, or handle obligation enforcement in your application logic after reading the policy object. | ||
|
|
||
| </TabItem> | ||
| <TabItem value="js" label="JavaScript"> | ||
|
|
||
| ```typescript | ||
| const plaintext = await client.read({ | ||
| source: { type: 'buffer', location: encryptedBytes }, | ||
| fulfillableObligationFQNs: [ | ||
| 'https://example.com/obl/audit/value/log', | ||
| 'https://example.com/obl/watermark/value/apply', | ||
| ], | ||
| }); | ||
| ``` | ||
|
|
||
| </TabItem> | ||
| </Tabs> | ||
|
|
||
| --- | ||
|
|
||
| ### Max Manifest Size (Go only) | ||
|
|
||
| Limit the maximum size of the TDF manifest that the SDK will parse. This is a defence against malformed or malicious TDFs with abnormally large manifests. | ||
|
|
||
| ```go | ||
| import ( | ||
| "bytes" | ||
|
|
||
| "github.com/opentdf/platform/sdk" | ||
| ) | ||
|
|
||
| tdfReader, err := client.LoadTDF( | ||
| bytes.NewReader(encryptedBytes), | ||
| sdk.WithMaxManifestSize(1 * 1024 * 1024), // 1 MB limit | ||
| ) | ||
| ``` | ||
|
|
||
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.