Skip to main content

Communication Flow

Understanding the communication flow helps troubleshoot issues and optimize performance. This page gives a high-level view of how operations flow through the system from Oracle Database to DuoKey Cockpit and back.

API reference: Detailed API endpoints and request/response formats are documented separately in the Developer Docs.

Overview​

Communication overview
Oracle Database
Oracle TDE
PKCS#11 calls
PKCS#11 Library
PKCS#11 Interface
internal API
DuoKey SDK
HTTPS
Network
HTTPS / TLS
request
DuoKey Cockpit
Cockpit API
Key Management
Backend HSMSecurosys
OraclePKCS#11 librarySDKCockpit / KMSBackend HSM

Oracle calls flow left-to-right to the backend HSM; responses return along the same path.

Typical Operation Flow​

Initialization Flow​

Initialization flow
Oracle to PKCS#11C_Initialize(NULL)
PKCS#11 LayerRead pkcs11.toml (server_url + access_token)
initialize connection
SDK to CockpitRequest with access_token bearer credential (access_guid in server_url is only routing)
CockpitValidate access_tokenResolve tenant from (app_id, access_guid)
vault information
SDK LayerKeep connection alive
initialized
PKCS#11 to OracleCKR_OK

Steps:

  1. Oracle calls C_Initialize(): Library initialization begins
  2. Read Configuration: Library reads server_url (containing the non-secret access_guid routing id) and access_token from pkcs11.toml
  3. Authentication: The library presents its access_token bearer credential to the Cockpit on its first request
  4. Server-side Validation: The Cockpit validates the access_token and resolves the tenant from (app_id, access_guid); no separate token exchange is performed
  5. Vault Verification: Verify access to specified vault
  6. Return Success: Library ready for operations

Session Creation Flow​

Session creation flow
Oracle to PKCS#11C_OpenSession(slot, flags)
PKCS#11 LayerValidate slotCreate session objectInitialize handle mapping table
session handle
PKCS#11 to OracleSession handle returned

No API call is needed for session creation — sessions are managed locally.

Steps:

  1. Oracle calls C_OpenSession(): Request new session
  2. Validate Slot: Ensure slot ID is valid
  3. Create Session: Create internal session object
  4. Initialize Tables: Create handle mapping table for session
  5. Return Handle: Return session handle to Oracle

Note: Session creation doesn't require API calls. Sessions are managed locally.

Login Flow​

Login flow
Oracle to PKCS#11C_Login(session, user:1234)
PKCS#11 LayerConfirm access_token available (pkcs11.toml)Mark session as logged in
CKR_OK
PKCS#11 to OracleSuccess

The bearer token was already presented in C_Initialize(); C_Login performs no additional API call.

Steps:

  1. Oracle calls C_Login(): Request session login
  2. Check Token: Verify the access_token bearer credential is configured in pkcs11.toml
  3. Mark Session: Mark session as authenticated
  4. Return Success: Return CKR_OK

Note: For DuoKey PKCS#11, authentication happens during C_Initialize(), when the library presents its access_token bearer credential to the Cockpit. The C_Login() function confirms the token is available but doesn't perform additional API calls.

Key Generation Flow​

Key generation flow
Oracle to PKCS#11C_GenerateKey(session, mechanism, template)
PKCS#11 LayerParse templateExtract key type and sizeExtract label
generate key request
SDK to CockpitGenerate key (algorithm, key size, label)
Backend HSMGenerate key material
key UUID + metadata
Cockpit to SDKKey created response
UUID received
PKCS#11 LayerCreate handle mappingStore handle to UUID
key handle
PKCS#11 to OracleKey handle returned

Steps:

  1. Oracle calls C_GenerateKey(): Request key generation
  2. Parse Template: Extract key attributes (type, size, label)
  3. Build API Request: Create key generation request
  4. API Call: Send the key-generation request to the Cockpit
  5. HSM Generation: Backend HSM generates key
  6. Receive UUID: Cockpit returns key UUID
  7. Create Handle: Map UUID to PKCS#11 handle
  8. Return Handle: Return handle to Oracle

Encryption Flow​

Encryption flow
Oracle to PKCS#11C_Encrypt / C_WrapKey (session, master key handle, tablespace key)
PKCS#11 LayerLookup UUID for handleParse mechanism (AES-CBC / AES-CBC-PAD)Extract parameters (IV)
wrap request
SDK to CockpitWrap with master key (AES-CBC / AES-CBC-PAD, IV)
Backend HSMPerform AES-CBC(-PAD) wrap
wrapped key (length-preserving)
Cockpit to SDKWrapped data
wrapped key
PKCS#11 to OracleWrapped result

Only the master-key path reaches the Cockpit. Bulk table/tablespace AES crypto stays local (AES-NI).

Steps:

  1. Oracle calls C_Encrypt() / C_WrapKey(): Request a wrap on the master-key path (e.g. protecting a tablespace key)
  2. Handle Lookup: Find UUID for provided master key handle
  3. Parse Mechanism: Extract algorithm (AES-CBC / AES-CBC-PAD) and IV
  4. Build Request: Create wrap request
  5. API Call: Send the wrap request to the Cockpit
  6. HSM Wrap: Backend HSM performs the length-preserving AES-CBC(-PAD) wrap
  7. Receive Wrapped Key: Get wrapped data
  8. Return Result: Return to Oracle

Note: The wrap uses a length-preserving AES-CBC / AES-CBC-PAD mechanism. An expanding AES-GCM envelope must not be used on this path — it breaks Oracle's SET KEY with ORA-00600 [kcbtse_populate_tbskey_1]. Bulk table and tablespace encryption is performed locally by Oracle using AES-NI and never leaves the database.

Decryption Flow​

Decryption flow
Oracle to PKCS#11C_Decrypt / C_UnwrapKey (session, master key handle, wrapped key)
PKCS#11 LayerLookup UUID for handleParse mechanism (AES-CBC / AES-CBC-PAD)Extract parameters (IV)
unwrap request
SDK to CockpitUnwrap with master key (AES-CBC / AES-CBC-PAD, IV)
Backend HSMPerform AES-CBC(-PAD) unwrap
tablespace key
Cockpit to SDKUnwrapped data
tablespace key
PKCS#11 to OracleUnwrapped result

Only the master-key path reaches the Cockpit. Bulk table/tablespace AES crypto stays local (AES-NI).

Steps:

  1. Oracle calls C_Decrypt() / C_UnwrapKey(): Request an unwrap on the master-key path (e.g. recovering a tablespace key at keystore open / SET KEY)
  2. Handle Lookup: Find UUID for provided master key handle
  3. Parse Mechanism: Extract algorithm (AES-CBC / AES-CBC-PAD) and IV
  4. Build Request: Create unwrap request
  5. API Call: Send the unwrap request to the Cockpit
  6. HSM Unwrap: Backend HSM performs the length-preserving AES-CBC(-PAD) unwrap
  7. Receive Tablespace Key: Get the unwrapped key
  8. Return Result: Return to Oracle

Object Search Flow​

Object search flow
Oracle to PKCS#11C_FindObjectsInit(session, template)
PKCS#11 LayerParse templateExtract search criteriaStore search state
C_FindObjects(session, maxObjects)
PKCS#11 to SDKSearch objects request
SDK to CockpitSearch objects (label, class)
matching objects (UUIDs)
PKCS#11 LayerCreate handles for UUIDsStore mappings
handle array
Oracle to PKCS#11C_FindObjectsFinal(session)
PKCS#11 to OracleClear search state, CKR_OK

Steps:

  1. C_FindObjectsInit(): Initialize search with template
  2. Parse Template: Extract search criteria (label, class, etc.)
  3. C_FindObjects(): Execute search
  4. API Call: Send the object-search request to the Cockpit
  5. Receive UUIDs: Get matching object UUIDs
  6. Create Handles: Map UUIDs to handles
  7. Return Handles: Return handle array to Oracle
  8. C_FindObjectsFinal(): Clean up search state

Error Handling Flow​

Network Error Handling​

This flow is kept as a sequence diagram because it has nested retry branching (timeout → backoff → retry → success or max-retries) that a linear diagram cannot represent faithfully.

Authentication Error Handling​

Authentication error handling
PKCS#11 to SDKAPI request
SDK to CockpitRequest with access_token bearer credential
CockpitValidate access_token server-side
Valid token200 OK
SDK to PKCS#11Success
Invalid or revoked access_token401 Unauthorized
SDK to PKCS#11CKR_PIN_INCORRECT

Note: The access_token is a single static bearer credential (distinct from the non-secret access_guid routing id in server_url). There is no token endpoint and no refresh cycle, so a rejected token is a terminal error (check access_token in pkcs11.toml) rather than something the library retries.

HSM Error Handling​

HSM error handling
PKCS#11 to SDKOperation request
SDK to CockpitAPI request
Cockpit to HSMOperation
HSM error500 Internal Server Error
CKR_DEVICE_ERROR
Object not found404 Not Found
CKR_OBJECT_HANDLE_INVALID
Invalid parameters400 Bad Request
CKR_ARGUMENTS_BAD

The SDK layer maps each backend outcome to the matching PKCS#11 return code.

Performance Optimization​

Connection Reuse​

Connection reuse
First request
Create connection
Cache connection
subsequent requests
Reuse connection

After the first request the connection is cached; subsequent requests reuse the cached connection.

Benefits:

  • Eliminates TCP handshake overhead
  • Reduces connection establishment time
  • Improves overall throughput

Bearer Token​

The library authenticates every request with an access_token bearer credential from pkcs11.toml. The access_guid embedded in the app proxy server_url is a separate, non-secret routing id. There is no token endpoint and no refresh cycle: the same access_token is presented on each request and validated server-side by the Cockpit, which resolves the tenant from (app_id, access_guid).

Bearer token authentication
Request
Attach access_token bearer credential
Cockpit validates token
Resolve tenant from app_id + access_guid
Authorized

Benefits:

  • No token-exchange round trips
  • No runtime secret to rotate (no client_id / client_secret)
  • Connection keep-alive reduces per-operation TLS handshakes

Handle Caching​

Handle caching
Find object
UUID in cache?
YesReturn cached handle
NoCreate new handle
store in cache
Store and return handle
Use handle

A cached UUID returns its handle directly; a new UUID is assigned a handle and stored before use.

Benefits:

  • Avoids duplicate API calls
  • Faster handle resolution
  • Reduced network traffic

Monitoring and Debugging​

Request Tracing​

Enable debug logging to trace requests:

export DKE_PKCS11_LOGGING_LEVEL=debug
export DKE_PKCS11_LOGGING_FOLDER=/var/log/dke-pkcs11

Log Output:

[2025-12-19 10:30:45] [DEBUG] C_Initialize() called
[2025-12-19 10:30:45] [DEBUG] Reading pkcs11.toml (server_url, access_token)
[2025-12-19 10:30:45] [INFO] Connecting to DuoKey Cockpit: https://cockpit-api-dev.duokey.cloud
[2025-12-19 10:30:46] [INFO] access_token bearer credential validated by Cockpit
[2025-12-19 10:30:46] [DEBUG] C_Initialize() completed: CKR_OK

Performance Metrics​

Monitor key metrics:

  • Request Latency: Time from Oracle call to response
  • API Latency: Time for DuoKey Cockpit API calls
  • Error Rate: Percentage of failed requests
  • Auth Failures: Count of rejected access_token bearer credentials

Network Monitoring​

Monitor network traffic:

  • HTTPS Connections: Number of active connections
  • Request/Response Sizes: Payload sizes
  • Retry Count: Number of retries per request
  • Timeout Events: Frequency of timeouts

Best Practices​

Error Handling​

  1. Retry Transient Errors: Network errors, timeouts
  2. Don't Retry Auth Errors: Invalid credentials
  3. Log All Errors: For troubleshooting
  4. Return Appropriate Codes: Translate to PKCS#11 codes

Performance​

  1. Reuse Connections: Use connection pooling
  2. Keep Connections Alive: Amortize TLS handshakes across operations
  3. Batch Operations: When possible (future)
  4. Monitor Latency: Track performance metrics

Security​

  1. Use TLS: All connections encrypted
  2. Validate Certificates: Strict certificate validation
  3. Secure Credentials: Never log the access_token (or the access_guid, unnecessarily)
  4. Protect pkcs11.toml: Treat the access_token as a secret; restrict file permissions. The access_guid is not secret by itself but still identifies the app, so protect the whole file

Next Steps​