Additional Credentials and Activation/Deactivation
Overview
For security reasons or convenience, you may want to add more than one signing key to Due Vaults. You can add several keys and store them as backups for when the main key is lost, or organize key rotation for security considerations.
While the first credential is automatically approved during creation, additional credentials require manual approval. You need to approve newly added keys with a previously created and approved credential. This ensures that even if your API key is compromised, an attacker cannot steal money by adding an additional key.
This allows you to:
- Create backup credentials for recovery scenarios
- Implement key rotation for enhanced security
Note: All credentials have equal access to vault operations - there are no different permission levels or restricted access credentials.
Prerequisites
- Existing active and approved credential (from the initial setup)
- OpenSSL toolkit installed
- API access token
Step 1: Create Additional Credential
Initialize Additional Credential Creation
The process is identical to creating the first credential - using Pattern 1: Direct JSON Signing. See Create Credential guide for detailed steps.
curl --location 'https://api.due.network/v1/vaults/credentials/init' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer <token>' \
--data '{
"kind": "Key",
"name": "Backup key 1"
}'Generate New Key Pair
Generate a separate key pair for the additional credential:
# Generate new private key
openssl ecparam -genkey -name prime256v1 -out private_backup.pem
# Generate corresponding public key
openssl ec -in private_backup.pem -pubout -out public_backup.pemPrepare Challenge Data
Create a JSON file with the challenge data to avoid issues with escape sequences:
# Create JSON file with clientDataHash and public key
cat > challenge.json << EOF
{"clientDataHash":"<clientDataHash_from_response>","publicKey":$(cat public_backup.pem | jq -Rs .)}
EOFSign and Submit Additional Credential
Sign the challenge data:
# Sign the JSON data from file (removing any trailing newline before signing)
cat challenge.json | tr -d '\n' | openssl dgst -sha256 -sign private_backup.pem | xxd -p | tr -d '\n'Submit the credential:
curl --location 'https://api.due.network/v1/vaults/credentials' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer <token>' \
--data '{
"kind": "Key",
"signature": "<your_hex_signature>",
"publicKey": "<your_public_key_pem>",
"challenge": "<challenge_from_init_response>"
}'Response for additional credential:
{
"id": "passkey_xpbaGnRJUMsrmx4is6EKE",
"kind": "Key",
"algorithm": "ECDSA:256:P-256",
"location": {
"deviceType": "",
"deviceOS": ""
},
"name": "Backup key 1",
"publicKey": "-----BEGIN PUBLIC KEY-----\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAENsRgOcOnWHVRyDI1JnCbh1+QglIF\n4ufYtmiP1c6Hxgiaeoxt2ZLzeQcCqvSIUSR15nZRbpYDABxNab9rhpSzSQ==\n-----END PUBLIC KEY-----\n",
"hasWalletAccess": true,
"createdAt": "2025-09-15T11:29:36.970110202Z",
"approveUntil": "2025-09-15T11:42:46Z",
"isActive": true
}Note the difference from first credential:
"isActive": true- credential is active (same as first credential)"approveUntil": "2025-09-15T11:42:46Z"- has a deadline, meaning it needs approval
Step 2: Approve Additional Credential
Additional credentials require approval before the approveUntil deadline. Approval must be done using an existing fully approved credential.
Note: This process uses Pattern 2: Challenge-Response Flow.
Request Approval Challenge
curl --location 'https://api.due.network/v1/vaults/credentials/approve' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer <token>' \
--data '{
"payload": {
"credentialId": "passkey_xpbaGnRJUMsrmx4is6EKE"
}
}'You'll receive a 403 error with a challenge (standard Pattern 2 response).
Sign Approval Challenge
Important: Sign with your existing fully approved credential's private key, not the new credential being approved.
# Sign the challenge with existing credential's private key
echo -n "<clientData_from_response>" | base64 -d | openssl dgst -sha256 -sign private.pem | base64 -w 0 | tr '+/' '-_' | tr -d '='Complete Approval
curl --location 'https://api.due.network/v1/vaults/credentials/approve' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer <token>' \
--data '{
"payload": {
"credentialId": "passkey_xpbaGnRJUMsrmx4is6EKE"
},
"signature": {
"challengeIdentifier": "<challengeIdentifier_from_response>",
"firstFactor": {
"kind": "Key",
"credentialAssertion": {
"credId": "passkey_xonETR6gAv3wIyhy8ehjx",
"clientData": "<original_clientData>",
"signature": "<your_signature>"
}
}
}
}'Response after successful approval:
{
"id": "passkey_xpbaGnRJUMsrmx4is6EKE",
"kind": "Key",
"algorithm": "ECDSA:256:P-256",
"location": {
"deviceType": "",
"deviceOS": ""
},
"name": "Backup key 1",
"publicKey": "...",
"hasWalletAccess": true,
"createdAt": "2025-09-15T11:29:36.97011Z",
"approveUntil": null,
"isActive": true
}Notice after successful approval:
"approveUntil": null- no longer requires approval, fully approved and ready to use
Step 3: Credential Deactivation
You can deactivate credentials that are no longer needed. This also uses Pattern 2.
Request Deactivation
curl --location 'https://api.due.network/v1/vaults/credentials/deactivate' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer <token>' \
--data '{
"payload": {
"credentialId": "passkey_xpbaGnRJUMsrmx4is6EKE"
}
}'Sign and Complete Deactivation
Sign the challenge with an active credential and submit following Pattern 2 structure.
Response after deactivation:
{
"id": "passkey_xpbaGnRJUMsrmx4is6EKE",
"isActive": false
}The credential is now deactivated ("isActive": false).
Updated about 1 month ago