-
Notifications
You must be signed in to change notification settings - Fork 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:
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:
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:
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
// 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 -> ResourceLocator2. PEM Parsing Helper
extension KasMetadata {
public static func fromPEM(
endpoint: String,
publicKeyPEM: String,
curve: Curve = .secp256r1
) throws -> KasMetadata
}3. High-Level Decryption API
public func decryptNanoTDF(
nanoTDF: Data,
kasRewrapClient: KASRewrapClient
) async throws -> Data4. Convenience Constructors
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