Credential vault & rotation
Outcome
Trading-partner credentials are stored encrypted in the vault, never displayed in the UI, rotated cleanly without an outage window, and have a clear audit trail of who rotated what and when.
Prerequisites
| Role | What it lets you do |
|---|---|
PLATFORM_SUPPORT, PLATFORM_READONLY | View secret names and last-rotated dates |
PLATFORM_ADMIN | Set / rotate credentials |
A partner record (see 2.1 — Onboard a new partner).
How the vault works
Trading-partner secrets live in Azure Key Vault (the same Key Vault that holds every other platform secret). The trading-partner record itself stores only secret names — never values.
- The UI submits secrets to the gateway, which writes them to Azure Key Vault using the gateway's Managed Identity.
- The partner row in Postgres stores only the secret names (e.g.
passwordSecretName,privateKeySecretName,receiptSignaturePublicKeySecretName) plus the rotation metadata:credential_last_rotated_at,credential_last_rotated_by,credential_secret_names. - The UI never sees secret values — only the metadata.
- Outbound transactions resolve the secret name to a value on demand inside the gateway.
- A Key Vault entry is deleted only when the partner record is deleted. There is no per-credential clear action in the console.
Steps to set credentials for the first time
Open the partner detail at
/trading-partners/:id→ Credentials tab. It has one row per credential type the partner's protocol uses, each showing the vault secret name orNot set:Protocol Credential types SFTPSFTP password, SFTP private key RESTREST bearer token, REST client secret MFTMFT OAuth2 client secret (or MFT signed-JWT private key, for signed-JWT auth), and MFT receipt verification public key Click
Set valueon the row. The Rotate credential dialog opens with that credential type selected. It has three fields:- Credential type, preselected; you can switch it.
- New value, a text area. Paste a PEM key whole.
- Type
<code>to confirm, where<code>is the partner's registry partner code, or its name if it has no code. Rotate credential stays disabled until the value is non-empty and the token matches.
Click
Rotate credential. The dialog closes with a confirmation toast. The row now shows the secret name (trading-partner-<partnerId>-<credential type>), and the Overview tab's Credential rotated / Rotated by fields update.Run
Test connection(see 2.5 — Probe & test connection).
Steps to rotate credentials
Rotation is the same flow as initial set. Every write for one credential type goes to the same vault secret name, so a rotate overwrites the prior value:
Click
Rotateon the row in the Credentials tab.Submit the new value as above. Outbound traffic uses the new value on the next request that resolves it.
Check the Overview tab: Credential rotated is the new timestamp.
Run
Test connectionto confirm the new secret is accepted.
Coordinating rotation with the partner
Most partner side-rotations are scheduled — you know about them in advance. The recommended sequence:
If the partner cannot expose the new secret until cutover, schedule the rotate inside the partner's first-acceptance window for the new secret. Probe immediately to confirm.
Removing credentials
There is no per-credential clear action. A partner's vault secrets are purged when the partner is deleted (Delete in the page header, which soft-deletes the row). Before that, confirm no active routing rule still picks the partner.
Audit trail
Every credential write records an audit event
(EDI_TRADING_PARTNER_CREDENTIAL_WRITTEN) with the partner id and the
credential type, never the value. The partner's Audit tab shows it as
action WRITE, purpose trading_partner.credential.<credential type>, with
the actor and source IP.
Validation
| Check | Expected |
|---|---|
| Rotate credential closes with a success toast | Yes; the row shows the secret name. |
| Probe succeeds with new credentials | Yes. |
| The Audit tab carries the credential row | Yes. |
| Old credential is unusable for outbound | Yes — no fallback to prior value. |
Troubleshooting
| Symptom | Cause | Fix |
|---|---|---|
| Rotate credential stays disabled | The confirm token does not match (extra whitespace, case), or the value is empty | Re-type the partner code exactly as the dialog shows it. |
| Outbound traffic still fails after rotate | Partner has not yet promoted the new secret on their side | Coordinate with partner; do not roll back — the audit trail is cleaner with one well-known issue than two rotations. |
| Probe succeeds but inbound poll fails with auth error | Inbound credential is separate (SFTP partners sometimes provision two logins); only one was rotated | Rotate the inbound credential too. |