arkavo-org / arkavo-org/OpenTDFKit
Improve NanoTDF Developer Experience
- Dominant language
- Swift
- Stars
- 1
- Forks
- 1
- Avg merge
- 9d 4h
- Merged PRs (30d)
- 1
Description
## Summary
While integrating NanoTDF encryption into an iOS app, several API design aspects could be improved to enhance developer experience.
## Current Challenges
### 1. Failable Initializers Without Clear Documentation
`ResourceLocator` has a failable initializer but the conditions for failure aren't immediately clear from the API:
```swift
public init?(protocolEnum: ProtocolEnum, body: String, identifier: Data? = nil)
```
**Impact**: Developers need to handle optionals and understand validation rules (e.g., body length 1-255 bytes)
### 2. PublicKeyType Requires Manual PEM Parsing
When working with PEM-formatted public keys from a KAS endpoint, developers must manually:
- Strip PEM headers/footers
- Base64 decode
- Parse DER representation
- Convert to `P256.KeyAgreement.PublicKey`
**Current code needed**:
```swift
let base64String = pem
.replacingOccurrences(of: "-----BEGIN PUBLIC KEY-----", with: "")
.replacingOccurrences(of: "-----END PUBLIC KEY-----", with: "")
.replacingOccurrences(of: "\n", with: "")
.trimmingCharacters(in: .whitespacesAndNewlines)
guard let derData = Data(base64Encoded: base64String) else {
throw Error()
}
let publicKey = try P256.KeyAgreement.PublicKey(derRepresentation: derData)
```
### 3. Module vs Instance Method Naming Collision
The global function `createNanoTDF(kas:policy:plaintext:)` can collide with instance methods, requiring:
```swift
let nanoTDF = try await OpenTDFKit.createNanoTDF(kas: kasMetadata, policy: &policy, plaintext: content)
```
### 4. Missing High-Level Decryption API
While encryption has `createNanoTDF()`, there's no equivalent high-level `decryptNanoTDF()` function that handles:
- Parsing NanoTDF structure
- KAS rewrap
- Symmetric key derivation
- Payload decryption
Developers must manually orchestrate these steps using low-level APIs.
## Suggested Improvements
### 1. Throwing Initializers or Validation Helpers
```swift
// Option A: Throwing init
public init(protocolEnum: ProtocolEnum, body: String, identifier: Data? = nil) throws
// Option B: Static factory with clear errors
public static func create(protocolEnum: ProtocolEnum, body: String) throws -> ResourceLocator
```
### 2. PEM Parsing Helper
```swift
extension KasMetadata {
public static func fromPEM(
endpoint: String,
publicKeyPEM: String,
curve: Curve = .secp256r1
) throws -> KasMetadata
}
```
### 3. High-Level Decryption API
```swift
public func decryptNanoTDF(
nanoTDF: Data,
kasRewrapClient: KASRewrapClient
) async throws -> Data
```
### 4. Convenience Constructors
```swift
extension Policy {
public static func embedded(
json: String,
ownerID: String? = nil
) throws -> Policy
}
```
## Use Case
iOS app encrypting user-generated content with policy-based access control, using a remote KAS at `https://kas.example.com/kas`.
## Priority
Medium - These are quality-of-life improvements, not blockers. Current API is functional but requires more boilerplate.
## Related
- NanoTDF specification compliance
- iOS/mobile developer experience
- API ergonomics for common use cases
Contributor guide
No contributing guide indexed for this repository
Research direction
Start by reviewing the ResourceLocator initializer, PublicKeyType handling, createNanoTDF entry point, and the low-level decryption APIs named in the issue. Agree on which API improvements are in scope and define completion around the selected constructors, PEM helper, and high-level decryption flow being usable without the current boilerplate.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- swift
- Domain
- api, developer-experience, mobile-dev
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Stale
- Clarity
- Needs clarification
- Newbie friendliness
- 35/100