Migrate kepairs
When migrating between DigiCert® Software Trust Manager environments — such as moving from one region to another, consolidating accounts, or transitioning from on-premises to cloud — you need to transfer your keypairs to the target environment. Doing this manually through the Software Trust Manager UI, one keypair at a time, is time-consuming and error-prone at scale.
The keypair migration automation scripts streamline this process by enabling bulk export and import of keypairs across Software Trust Manager instances. Using a simple CSV-driven workflow, you can migrate multiple keypairs in a single operation while maintaining the security controls your organization relies on.
The migration follows a structured, multi-step workflow that enforces STM's two-person authorization model - a requester initiates the export, and a separate approver must authorize it before any private key material can be downloaded. This separation of duties ensures that no single user can unilaterally extract keypairs from your environment.
The workflow is available for both Mac/Linux (Bash) and Windows (PowerShell), with no external dependencies beyond standard system tools.
The workflow consists of the following steps:
(Optional) Remove keypairs from Teams - Required only if the Teams feature is enabled; sets keypairs to open so they can be exported.
Request export - The requester submits export requests for all keypairs listed in the input CSV.
Approve export - A different admin approves the pending export requests.
Download keys - The requester downloads the encrypted private keys and their one-time passphrases.
Import keypairs - The importer loads the keypairs into the target Software Trust Manager environment.
Roles:
Role | Responsibility |
|---|---|
Requester | Initiates the export, downloads the keys after approval. |
Approver | Approves the export requests (must be a different admin in the same account. |
Importer | Imports the keypairs into the target environment. The requester and importer may be the same person if they have credentials on both environments. |
Platform support
Scripts are available for both macOS/Linux (Bash) and Windows (PowerShell), with no external tool dependencies on Windows. macOS/Linux scripts use standard utilities (curl, jq, openssl).
Supported key algorithms
The scripts support all standard Software Trust Manager key types:
RSA (2048, 3072, 4096-bit)
EdDSA (Ed25519).
EdDSA (Ed25519).
Opmerking
These scripts support standard disk-based keypairs only. GPG keypairs are not supported.
Belangrijk
Ensure that the keypair is an open keypair (not assigned to a team), OR the Team feature is disabled in your account.
Prerequisites
PowerShell 5.1+ (included with Windows 10/11)
No additional tools required
Remove Keypairs from Teams (Only if Teams is enabled). This sets keypairs to 'open' so they can be exported using the standard two-person approval flow. To remove the kepairs from team use the follwoing command:
.\0_remove_from_teams.ps1 ` -InputCsv keypairs.csv ` -BaseUrl "https://clientauth.dcone.cluster.local" ` -AccountId "06ef4889-f2c7-4b28-9789-dba19355dccf" ` -ApiKey "<admin-api-key>" ` -ClientCert "C:\path\to\admin_cert.p12" ` -ClientCertPass "<p12-password>"Belangrijk
After migration is complete, you can reassign the keypairs back to their respective Teams in the source environment if they should remain protected.
Execution policy
If you get an error about script execution being disabled, run this once in an elevated (admin) PowerShell:
Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser
Input CSV format
Create a CSV file (e.g., keypairs.csv) with no spaces after commas:
keypair_alias,keypair_id,algorithm my-signing-key,5057601f-bc10-4289-bfa3-5d5c075efccd,RSA code-sign-key,a1b2c3d4-e5f6-7890-abcd-ef1234567890,ECDSA ed-key,9de22901-5df0-41ba-a297-8d102184d751,EdDSA
Input parameter | Description |
|---|---|
| The name/alias of the keypair (used as the alias when importing) |
| The UUID of the keypair in the source environment |
| The key algorithm — one of: |
How to find your keypair details
You can find these values in the Software Trust Manager under Keypairs, or using the API:
$cert = New-Object System.Security.Cryptography.X509Certificates.X509Certificate2("C:\path\to\cert.p12", "<password>")
Invoke-RestMethod -Uri "https://<clientauth-host>/signingmanager/api/v1/keypairs?account_id=<account-id>" `
-Headers @{"x-api-key"="<your-api-key>"} -Certificate $cert | ConvertTo-JsonEnvironment hosts
Environment | Base URL |
|---|---|
GP2 (USA) | https://clientauth.one.digicert.com |
Demo | https://clientauth.demo.one.digicert.com |
Stage (AZ) | https://clientauth.one.stage.az.digicert.net |
Japan | https://clientauth.one.digicert.co.jp |
Japan (Demo) | https://clientauth.demo.one.digicert.co.jp |
Switzerland | https://clientauth.one.ch.digicert.com |
Switzerland (Demo) | https://clientauth.demo.one.ch.digicert.com |
Netherlands | https://clientauth.one.nl.digicert.com |
Netherlands (Demo) | https://clientauth.demo.one.nl.digicert.com |
Australia | https://clientauth.one.au.digicert.com |
Australia (Demo) | https://clientauth.demo.one.au.digicert.com |
India | https://clientauth.one.digicert.co.in |
UPS | https://clientauth.one.ups.digicert.com |
Oracle | https://clientauth.one.oracle.digicert.com |
Microsoft | https://clientauth.microsoft.one.digicert.com |
Belangrijk
Always use the clientauth prefixed host. This enables mutual TLS (mTLS) which is required for multi-factor authentication on for operations like keypair export.
Steps to follow for using the migrate keypairs automation scripts:
Request export (Requester)
The user initiating the keypair migration from the source environment can initiate the keypair migration process by using this script.
For each keypair listed in the input CSV, the script submits an export request to the DigiCert Software Trust Manager API. Each request generates a unique export request ID, which is required for the approval step before the keypair can be exported.
Command:
.\1_request_export.ps1 ` -InputCsv keypairs.csv ` -BaseUrl "https://clientauth.dcone.cluster.local" ` -AccountId "06ef4889-f2c7-4b28-9789-dba19355dccf" ` -ApiKey "<requester-api-key>" ` -ClientCert "C:\path\to\requester_cert.p12" ` -ClientCertPass "<p12-password>"Expected output:
═══════════════════════════════════════════════════════════════ Step 1: Requesting Keypair Export Account: 06ef4889-f2c7-4b28-9789-dba19355dccf Input: keypairs.csv ═══════════════════════════════════════════════════════════════ [2] Requesting export for: my-signing-key (5057601f-bc10-4289-bfa3-5d5c075efccd) ✓ Success — export_request_id: 37be73ae-1c1c-4b02-9530-e04ff7ec47de ═══════════════════════════════════════════════════════════════ Done! Success: 1 | Failed: 0 Output written to: output_export_requests.csv Share this file with the approver for step 2. ═══════════════════════════════════════════════════════════════The generated output file
output_export_requests.csvfile is shared with the approver for the next step in the migration workflow.Approve export (Approver)
Use this script to approve pending keypair export requests. A different administrator in the same source account must perform this step; the user who initiated the export request cannot approve it. The script reads the export request IDs from the input CSV and approves each request, enforcing Software Trust Manager's two-person authorization model for secure keypair export.
Command:
.\2_approve_export.ps1 ` -InputCsv output_export_requests.csv ` -BaseUrl "https://clientauth.dcone.cluster.local" ` -AccountId "06ef4889-f2c7-4b28-9789-dba19355dccf" ` -ApiKey "<approver-api-key>" ` -ClientCert "C:\path\to\approver_cert.p12" ` -ClientCertPass "<p12-password>"Expected output:
═══════════════════════════════════════════════════════════════ Step 2: Approving Keypair Export Requests Account: 06ef4889-f2c7-4b28-9789-dba19355dccf Input: output_export_requests.csv ═══════════════════════════════════════════════════════════════ [2] Approving export for: my-signing-key (export_request_id: 37be73ae-...) ✓ Approved ═══════════════════════════════════════════════════════════════ Done! Approved: 1 | Failed: 0 Output written to: output_approved.csv Share this file with the requester for step 3 (download). ═══════════════════════════════════════════════════════════════The generated
output_approved.csvfile is returned to the requester for the next step in the migration workflow.Opmerking
Step 2 is not idempotent. Each export request can be approved only once. If the script completes only part of the approval process, do not rerun it using the same Step 2 input file. Requests that were already approved will fail, and the script may overwrite the output CSV with incorrect
Failedstatuses.If Step 2 partially succeeds, proceed in one of the following recovery options:
Continue to Step 3 using only the rows that were successfully approved.
Restart the workflow from Step 1 for the complete keypair list to generate a new set of export requests.
If you need to retry only the failed keypairs, first save the rows with an
Approvedstatus. Then create a new input CSV containing only the failed keypairs, rerun Steps 1 and 2 for that subset, and merge the newly approved results with the previously approved rows before proceeding to Step 3.Download keys (Requester)
Use this script to download approved keypairs. The original requester downloads the encrypted private key and one-time passphrase for each approved export. The script then generates a CSV containing all the information required to import the keypairs into the target Software Trust Manager environment.
Command:
.\3_download_keys.ps1 ` -InputCsv output_approved.csv ` -BaseUrl "https://clientauth.dcone.cluster.local" ` -AccountId "06ef4889-f2c7-4b28-9789-dba19355dccf" ` -ApiKey "<requester-api-key>" ` -ClientCert "C:\path\to\requester_cert.p12" ` -ClientCertPass "<p12-password>"Expected output:
═══════════════════════════════════════════════════════════════ Step 3: Downloading Exported Private Keys Account: 06ef4889-f2c7-4b28-9789-dba19355dccf Input: output_approved.csv ═══════════════════════════════════════════════════════════════ [2] Downloading key for: my-signing-key (export_request_id: 37be73ae-...) ✓ Downloaded successfully (password obtained) ═══════════════════════════════════════════════════════════════ Done! Downloaded: 1 | Failed: 0 Output written to: output_download.csv Share this file with the importer for step 4. ═══════════════════════════════════════════════════════════════Import keypairs (importer)
Use this script to import keypairs into the target environment. The user in the target Software Trust Manager environment imports the downloaded keypairs using the CSV generated in the previous step. Each keypair is imported with its original alias and algorithm.
Command:
.\4_import_keypairs.ps1 ` -InputCsv output_download.csv ` -BaseUrl "https://clientauth.one.stage.az.digicert.net" ` -AccountId "c5cb5795-c500-4d74-a632-190875de8364" ` -ApiKey "<target-user-api-key>" ` -ClientCert "C:\path\to\target_cert.p12" ` -ClientCertPass "<p12-password>"Expected output:
═══════════════════════════════════════════════════════════════ Step 4: Importing Keypairs into Target Environment Target Account: c5cb5795-c500-4d74-a632-190875de8364 Target URL: https://clientauth.one.stage.az.digicert.net Input: output_download.csv ═══════════════════════════════════════════════════════════════ [2] Importing keypair: my-signing-key (algorithm: RSA) ✓ Imported successfully — new keypair ID: 4d38a9f5-6162-4759-948d-65cc0a3e4225 ═══════════════════════════════════════════════════════════════ Done! Imported: 1 | Failed: 0 ═══════════════════════════════════════════════════════════════Opmerking
Step 4 is safe to re-run for failed rows only. If this step partially succeeds, do not re-run with the full original CSV because already-imported keypairs will fail with
keypair_duplicateerrors.As a recovery option, remove the successfully imported rows from the input CSV and re-run with only the failed rows. Alternatively, restart from Step 1 for the full key list if you prefer a clean slate.
Belangrijk
Ensure that the keypair is an open keypair (not assigned to a Team), OR the Team feature is disabled in your account.
Prerequisites
Remove Keypairs from Teams (Only if Teams is enabled). This sets keypairs to 'open' so they can be exported using the standard two-person approval flow. To remove the kepairs from team use the follwoing command:
./0_remove_from_teams.sh \
--input keypairs.csv \
--base-url https://clientauth.<your-source-host> \
--account-id <source-account-id> \
--api-key <admin-api-key> \
--client-cert /path/to/admin_cert.p12 \
--client-cert-pass <p12-password>Opmerking
After migration is complete, you can reassign the keypairs back to their respective Teams in the source environment if they should remain protected.
Tools required
The following command-line tools must be installed (all are available by default on macOS and most Linux distributions):
Tool
Purpose
urlMakes HTTP API calls
jqParses JSON responses
base64Encodes private key for transport
opensslConverts
.p12certificates to PEM formatCredentials required
Credentials
Description
API key
Your Software Trust Manager API key (x-api-key).
Client certificate
A
.p12(PKCS#12) file for mTLS authentication, along with its password3.Account ID
The UUID of the Software Trust Manager account.
Base URL
The
clientauthhost for your environment.Environment hosts
Environment
Base URL
GP2 (USA)
https://clientauth.one.digicert.com
Demo
https://clientauth.demo.one.digicert.com`
Stage (AZ)
https://clientauth.one.stage.az.digicert.net
Japan
https://clientauth.one.digicert.co.jp
Japan (Demo)
https://clientauth.demo.one.digicert.co.jp
Switzerland
https://clientauth.one.ch.digicert.com
Switzerland (Demo)
https://clientauth.demo.one.ch.digicert.com
Netherlands
https://clientauth.one.nl.digicert.com`
Netherlands (Demo)
https://clientauth.demo.one.ch.digicert.com
Australia
https://clientauth.one.au.digicert.com
Australia (Demo)
https://clientauth.demo.one.au.digicert.com
India
https://clientauth.one.digicert.co.in
UPS
https://clientauth.one.ups.digicert.com
Oracle
https://clientauth.one.oracle.digicert.com
Microsoft
https://clientauth.microsoft.one.digicert.com
Always use the clientauth prefixed host. This enables mutual TLS (mTLS) which is required for multi-factor authentication on sensitive operations like keypair export.
Input file
Create a CSV file named c
keypairs.csvwith the keypairs you want to migrate. The format is:
`csvkeypair_alias,keypair_id,algorithmmy-signing-key,5057601f-bc10-4289-bfa3-5d5c075efccd,RSAcode-sign-key,a1b2c3d4-e5f6-7890-abcd-ef1234567890,ECDSAed-key,9de22901-5df0-41ba-a297-8d102184d751,EdDSA
Input parameter | Description |
|---|---|
| The name/alias of the keypair (used as the alias when importing) |
| The UUID of the keypair in the source environment |
| The key algorithm — one of: |
How to find your keypair details
You can find these values in the Software Trust Manager under Keypairs, or using the API:
curl -s --cert <your-cert.p12>:<password> --cert-type P12 \
-H "x-api-key: <your-api-key>" \
"https://<clientauth-host>/signingmanager/api/v1/keypairs?account_id=<account-id>" | jq '.items[] | {alias, id, key_alg}'Steps to follow for using the migrate keypairs automation scripts:
Request export (Requester)
The user initiating the keypair migration from the source environment can initiate the keypair migration process by using this script.
For each keypair listed in the input CSV, the script submits an export request to the DigiCert Software Trust Manager API. Each request generates a unique export request ID, which is required for the approval step before the keypair can be exported.
Command:
./1_request_export.sh \ --input keypairs.csv \ --base-url https://clientauth.<your-source-host> \ --account-id <source-account-id> \ --api-key <requester-api-key> \ --client-cert /path/to/requester_cert.p12 \ --client-cert-pass <p12-password>Expected output: Creates
output_export_requests.csvcontaining:keypair_alias,keypair_id,algorithm,export_request_id my-signing-key,5057601f-...,RSA,37be73ae-1c1c-4b02-9530-e04ff7ec47de
The generated output file
output_export_requests.csvfile is shared with the approver for the next step in the migration workflow.Approve export (Approver)
Use this script to approve pending keypair export requests. A different administrator in the same source account must perform this step; the user who initiated the export request cannot approve it. The script reads the export request IDs from the input CSV and approves each request, enforcing Software Trust Manager's two-person authorization model for secure keypair export.
Command:
./2_approve_export.sh \ --input output_export_requests.csv \ --base-url https://clientauth.<your-source-host> \ --account-id <source-account-id> \ --api-key <approver-api-key> \ --client-cert /path/to/approver_cert.p12 \ --client-cert-pass <p12-password>Expected output: Creates
output_approved.csvcontaining:keypair_alias,keypair_id,algorithm,export_request_id,approval_status my-signing-key,5057601f-...,RSA,37be73ae-...,APPROVED
The generated
output_approved.csvfile is returned to the requester for the next step in the migration workflow.Opmerking
Step 2 is not idempotent. Each export request can be approved only once. If the script completes only part of the approval process, do not rerun it using the same Step 2 input file. Requests that were already approved will fail, and the script may overwrite the output CSV with incorrect
Failedstatuses.If Step 2 partially succeeds, proceed in one of the following recovery options:
Continue to Step 3 using only the rows that were successfully approved.
Restart the workflow from Step 1 for the complete keypair list to generate a new set of export requests.
If you need to retry only the failed keypairs, first save the rows with an
Approvedstatus. Then create a new input CSV containing only the failed keypairs, rerun Steps 1 and 2 for that subset, and merge the newly approved results with the previously approved rows before proceeding to Step 3.Download keys (Requester)
Use this script to download approved keypairs. The original requester downloads the encrypted private key and one-time passphrase for each approved export. The script then generates a CSV containing all the information required to import the keypairs into the target Software Trust Manager environment.
Command
./3_download_keys.sh \ --input output_approved.csv \ --base-url https://clientauth.<your-source-host> \ --account-id <source-account-id> \ --api-key <requester-api-key> \ --client-cert /path/to/requester_cert.p12 \ --client-cert-pass <p12-password>Expected output: Creates
output_download.csvcontaining:keypair_alias,keypair_id,algorithm,export_request_id,private_key_base64,passphrase my-signing-key,5057601f-...,RSA,37be73ae-...,LS0tLS1CRUdJ...,88rjLB6Bh00M6eK
Waarschuwing
Security warning: This file contains encrypted private keys and their passwords. Transfer it securely (encrypted email, secure file share, etc.). Delete it after import is complete.
Partial failure warning: Step 3 is not idempotent. Each approved export can only be downloaded once. If this step partially succeeds, do not re-run with the same Step 3 input because already-downloaded keys will fail and the script will overwrite the output CSV with incorrect
Failedstatuses, causing you to lose the data for keys that were already successfully downloaded.Recovery options: Either continue to Step 4 with only the rows that succeeded, or restart from Step 1 for the full key list to generate new export requests. If retrying only failures, save the succeeded downloaded rows, create a new input CSV containing only the failed keypairs, re-run Steps 1 → 2 → 3 for that subset, then merge the download results before proceeding to Step 4
Import keypairs (importer)
Use this script to import keypairs into the target environment. The user in the target Software Trust Manager environment imports the downloaded keypairs using the CSV generated in the previous step. Each keypair is imported with its original alias and algorithm.
Command:
./4_import_keypairs.sh \ --input output_download.csv \ --base-url https://clientauth.<your-target-host> \ --account-id <target-account-id> \ --api-key <importer-api-key> \ --client-cert /path/to/importer_cert.p12 \ --client-cert-pass <p12-password>Expected output:
═══════════════════════════════════════════════════════════════ Step 4: Importing Keypairs into Target Environment Target Account: c5cb5795-c500-4d74-a632-190875de8364 Target URL: https://clientauth.one.stage.az.digicert.net Input: output_download.csv ═══════════════════════════════════════════════════════════════ [2] Importing keypair: my-signing-key (algorithm: RSA) ✓ Imported successfully — new keypair ID: 4d38a9f5-6162-4759-948d-65cc0a3e4225 ═══════════════════════════════════════════════════════════════ Done! Imported: 1 Failed: 0 ═══════════════════════════════════════════════════════════════Belangrijk
Partial failure warning: Step 4 is safe to re-run for failed rows only. If this step partially succeeds, do not re-run with the full original CSV because already-imported keypairs will fail with
keypair_duplicate errorsRecovery options: Remove the successfully imported rows from the input CSV and re-run with only the failed rows. Alternatively, restart from Step 1 for the full key list if you prefer a clean slate.
Client Certificate Options
The scripts support both .p12 and .pem certificate formats:
Format | Arguments needed |
|---|---|
| |
| (no password needed) |
Converting .p12 to .pem (optional)
If you prefer to pre-convert your certificate:
openssl pkcs12 -in cert.p12 -out cert.pem -nodes -passin pass:<p12-password>
Opmerking
If you encounter issues not covered in the troubleshooting section, please contact DigiCert support with:
The error message from the script output
The HTTP status code
Your account ID (not your API key)
The environment/host you are using
Windows
Error | Cause | Solution |
|---|---|---|
| Not using clientauth. host or cert not loaded | Ensure base URL has clientauth. prefix and .p12 path/password are correct |
| Keypair with same alias already exists in target | Delete existing keypair or rename the alias in the CSV. |
| Empty line in CSV or incorrect format | Check CSV for trailing blank lines or extra commas. |
| Host unreachable or VPN not connected | Check network/VPN connection. |
| API key doesn't have permission | Verify the API key belongs to an admin with export/import permissions. |
(Step 3) | Trying to download before approval | Ensure step 2 completed successfully first |
| Connection timeout / host unreachable | Check VPN connection or verify the host URL |
Script execution disabled | PowerShell execution policy | Run |
Approval fails on re-run (step 2) | Export request was already approved; re-running overwrites output CSV | Save succeeded rows, re-run Steps 1→2 for failed keypairs only, then merge — see Partial Failure Recovery table. |
Download fails on re-run (step 3) | Key was already downloaded once; second download not allowed | Save succeeded rows, re-run Steps 1→2→3 for failed keypairs only, then merge — see Partial Failure Recovery table. |
SSL Certificate issues
For internal environments (e.g., dcone.cluster.local) with self-signed certificates, the scripts include the -k flag to skip server certificate verification. This is secure because:
Your client certificate is still sent and validated by the server.
Only the server's certificate verification is skipped.
This is only needed for internal/dev environments; production hosts have valid public certificates.
Partial failure recovery
Belangrijk
Never re-run Steps 2 or 3 with the same input after a partial success - the script will overwrite the output CSV with incorrect Failed statuses for already-processed rows.
Step | Idempotent? | Recovery |
|---|---|---|
Prerequisite (Step 0) – Remove from Teams | Yes | Re-run with the same |
Step 1 – Request export | Yes | Re-run with the same |
Step 2 – Approve export | No - requests can only be approved once | Continue to Step 3 with succeeded rows, or restart from Step 1 for all keys. If retrying failures only: save succeeded rows, re-run Steps 1→2 for failed subset, merge, then proceed. |
Step 3 – Download keys | No - keys can only be downloaded once | Continue to Step 4 with succeeded rows, or restart from Step 1 for all keys. If retrying failures only: save succeeded rows, re-run Steps 1→2→3 for failed subset, merge, then proceed. |
Step 4 – Import keypairs | Partial re-run safe | Remove succeeded rows from input CSV, re-run with only failed rows. |
Two-person authorization: Export requires both a requester and a separate approver. No single person can export keys alone.
mTLS: All API calls require mutual TLS via client certificates, ensuring strong identity verification.
Encrypted at rest: The exported private key is encrypted with a one-time password. Both are needed for import.
Secure the download CSV: output_download.csv contains sensitive material. Transfer securely and delete after use.
Audit trail: All export/approve/import operations are logged in Software Trust Manager audit log.
File summary
File | Purpose |
|---|---|
| Pre-requisite: removes keypairs from teams (run by admin, only if Teams enabled) |
| Requests keypair export (run by requester) |
| Approves export requests (run by approver) |
| Downloads encrypted keys (run by requester) |
| Imports keys to target (run by importer) |
| Example input CSV for reference (use from parent folder) |
Additional information:
The
.p12certificate is loaded natively via .NET. Noopensslconversion needed on Windows.CSV files generated on macOS/Linux are compatible with the Windows scripts and vice versa.
The PowerShell scripts use
Invoke-RestMethodwhich handles SSL/TLS natively using the Windows certificate store.The private key is base64-encoded in the CSV because the import API expects it in that format.
Failed rows are logged but don't stop processing of remaining rows.