Loading…
Loading…
Explains how backend credentials for SOAP services are encrypted at rest using AES-256 and pgcrypto. Covers key management, data handling, and API
To execute calls against a SOAP backend, the platform requires connection credentials. This document describes the mechanism used to securely store and handle these credentials.
The platform ensures that backend credentials are encrypted at rest and are never exposed in plaintext through the API or logs. The core of this system involves symmetric encryption performed within the platform's PostgreSQL database, with the encryption key managed externally by the API publisher.
This process involves two main components:
The plaintext credential material is never persisted in an unencrypted state.
The credential management process is designed to be write-only from an API perspective, ensuring that secrets, once stored, are never revealed.
Backend credentials are stored in the platform's PostgreSQL database within the corresponding backend-profile row. The credential data itself resides inside an encrypted envelope, which is a JSON object with the following structure:
{
"v": 1,
"alg": "pgcrypto-aes256",
"enc": "<base64 ciphertext>"
}
Encryption is handled by the pgcrypto extension for PostgreSQL, using the pgp_sym_encrypt function with the AES-256 symmetric encryption algorithm.
The following diagram illustrates the data flow for creating and using an encrypted credential:
sequenceDiagram
participant P as API Publisher
participant Admin as Admin API
participant DB as PostgreSQL Database
participant Runtime
participant Backend as SOAP Backend
P->>+Admin: POST /backend-profiles (with plaintext credential)
Admin->>+DB: Encrypt credential with S2R_CREDENTIAL_KEY<br/>(pgp_sym_encrypt)
DB-->>-Admin: Store encrypted envelope
Admin-->>-P: Respond with metadata (no plaintext)
Note over Runtime, Backend: Later, during a request...
Runtime->>+DB: Fetch encrypted credential for profile
DB-->>-Runtime: Return encrypted envelope
Note right of Runtime: Decrypts credential using<br/>S2R_CREDENTIAL_KEY
Runtime->>+Backend: Call backend with decrypted credential
Backend-->>-Runtime: SOAP ResponseThe symmetric encryption key is not stored in the database. Instead, it is supplied to the Admin API and Runtime services at startup via the S2R_CREDENTIAL_KEY environment variable. This key must be sourced from a secure secret store.
Key handling is governed by the following rules:
S2R_CREDENTIAL_KEY environment variable must be present at startup. If it is not set, services will refuse to start and will not operate on credentials.pgcrypto extension is available and that the provided key is well-formed.WARNING
Key Rotation: Rotating the S2R_CREDENTIAL_KEY will invalidate all existing encrypted credentials, as they will no longer be decryptable. The current, active key must be applied to every deployment of the Admin API and Runtime services. Treat this key as an operator-critical secret.
Credential values are write-only. When you create or update a backend profile, the plaintext credential is provided in the request body, but it is never returned in any API response.
Instead of the credential itself, API responses contain a metadata envelope indicating the status of the credential.
Example API Response Snippet:
{
"credentials": {
"set": true,
"lastUpdatedAt": "2026-04-18T14:02:11Z",
"lastUpdatedBy": "alice@example.gov.il"
}
}
This design allows clients to confirm if and when a credential was set, but prevents the credential value from ever being exposed. Plaintext credentials are also never written to service logs.
The encryption system is configured via a single environment variable.
| Name | Required | Description |
|---|---|---|
S2R_CREDENTIAL_KEY | true | The symmetric AES-256 key used for encrypting and decrypting backend credentials. If unset, services will fail to start with error S2R-ADM-0419 or S2R-RUN-0419. |
The structure of the plaintext credential payload, provided only during create or update operations, varies based on the backend's authentication type. All of the following payloads are encrypted and stored using the S2R_CREDENTIAL_KEY.
| Auth type | Credential Payload | Notes |
|---|---|---|
none | empty | No credentials are required. |
basic | { "username": "...", "password": "..." } | Standard HTTP Basic authentication. |
bearer | { "bearerToken": "..." } | Standard HTTP Bearer token authentication. |
api_key_header | { "apiKeyHeaderName": "...", "apiKeyValue": "..." } | A custom header name and value for API key authentication. |
oauth2_client_credentials | { "oauth2ClientSecret": "..." } | The client secret for an OAuth2 client credentials grant flow. Other OAuth2 fields (oauth2TokenEndpoint, oauth2ClientId, oauth2Scope, oauth2ExtraParams) are stored unencrypted as part of the backend profile. |
| mutual TLS | { "certPem": "...", "keyPem": "..." } | PEM-encoded client certificate and private key for mTLS. This is configured via credentials.mtls and activated by setting mtlsEnabled = true on the profile. It can be combined with other authentication types. |
NOTE
This documentation covers credentials for the platform's connection to a backend SOAP service. The security material for the inbound SOAP facade (i.e., credentials provided by an API consumer) is handled separately.
The platform provides an administrative endpoint to test backend connectivity without exposing stored credentials.
Safely tests DNS, TCP, and WSDL reachability for a configured backend profile. This operation does not return the stored credential.
POST /admin/v1/backend-profiles/{profileId}:test-connectionThe source does not specify the request or response body for this endpoint.
| Error Code | Service | Cause | Resolution |
|---|---|---|---|
S2R-ADM-0419 | Admin API | The S2R_CREDENTIAL_KEY environment variable was not set at startup. | Ensure the S2R_CREDENTIAL_KEY is correctly bound from your secret store and redeploy the service. |
S2R-RUN-0419 | Runtime | The S2R_CREDENTIAL_KEY environment variable was not set at startup. | Ensure the S2R_CREDENTIAL_KEY is correctly bound from your secret store and redeploy the service. |
If you encounter these errors after a new deployment, it typically indicates that the key binding was not applied to the new service revision.