---
title: "Get Platform Secret Key"
description: "This document outlines the execution flow initiated when a user attempts to test an integration connection from the IntegrationPlatformTestPage in the frontend. The core purpose of this flow is to ..."
last_updated: "2026-05-06T07:30:58.159818+00:00"
canonical_url: "https://www.doc0.dev/docs/49c89830-117b-4def-8edc-b5bcc50766e0/technical/how-it-works/get-platform-secret-key"
---

<details>
<summary>Relevant source files</summary>

The following files were used as context for generating this wiki page:

- [apps/app/src/app/app/orgId/integrations/platform-test/page.tsx](https://github.com/blade47/comp/blob/main/apps/app/src/app/(app)/%5BorgId%5D/integrations/platform-test/page.tsx)
- [apps/api/src/integration-platform/controllers/connections.controller.ts](https://github.com/blade47/comp/blob/main/apps/api/src/integration-platform/controllers/connections.controller.ts)
- [apps/api/src/integration-platform/services/credential-vault.service.ts](https://github.com/blade47/comp/blob/main/apps/api/src/integration-platform/services/credential-vault.service.ts)
</details>

This document outlines the execution flow initiated when a user attempts to test an integration connection from the `IntegrationPlatformTestPage` in the frontend. The core purpose of this flow is to securely retrieve and decrypt sensitive integration credentials (like API keys or OAuth tokens) from the backend's credential vault, enabling the system to verify the connection's validity.

The process begins with a user action in the browser, triggering an API call to the backend. The backend then fetches the encrypted credentials, decrypts them using a master secret key, and finally uses these plaintext credentials to perform the actual connection test. This secure handling ensures that sensitive information is never exposed directly to the frontend and is only decrypted when needed for operational purposes.

### 1. `IntegrationPlatformTestPage`

The execution begins on the `IntegrationPlatformTestPage` component, which is a React page responsible for rendering the user interface to manage and test integration connections. When a user navigates to this page, it loads and displays a list of available integration providers and existing connections.

When a user clicks the "Test" button associated with a specific connection, this action triggers the `handleTestConnection` function within this component. The page passes the unique `connectionId` and `providerSlug` of the selected connection to this handler. The primary role of this component in this flow is to initiate the client-side interaction that leads to the backend process.

Sources: [apps/app/src/app/(app)/[orgId]/integrations/platform-test/page.tsx:329-331](https://github.com/blade47/comp/blob/main/apps/app/src/app/(app)/%5BorgId%5D/integrations/platform-test/page.tsx#L329-L331)

### 2. `handleTestConnection`

The `handleTestConnection` function is an asynchronous client-side handler defined within the `IntegrationPlatformTestPage`. It is invoked when a user clicks the "Test" button for a particular integration connection.

This function takes the `connectionId` and `providerSlug` as arguments. Its main responsibility is to make an API call to the backend to initiate the actual connection test. It uses the `testConnection` mutation provided by the `useIntegrationMutations` hook (which internally uses `api.post`) to send an HTTP POST request to the backend's `/v1/integrations/connections/:id/test` endpoint. During this process, it updates the `isLoading` state to provide visual feedback to the user and logs the outcome (success or error message) to the frontend's action log.

Sources: [apps/app/src/app/(app)/[orgId]/integrations/platform-test/page.tsx:376-384](https://github.com/blade47/comp/blob/main/apps/app/src/app/(app)/%5BorgId%5D/integrations/platform-test/page.tsx#L376-L384)

### 3. `testConnection`

This method is a NestJS controller endpoint (`@Post(':id/test')`) within the `ConnectionsController` in the backend. It serves as the API entry point for testing an integration connection.

Upon receiving the POST request from the frontend, the method extracts the `connectionId` from the URL parameters. It first retrieves the `Connection` object from the database using `this.connectionService.getConnection(id)`. The crucial step for credential access is then performed: it calls `this.credentialVaultService.getDecryptedCredentials(connection.id)` to obtain the plaintext credentials required for the test. Depending on the `providerSlug` (e.g., 'aws'), it might delegate to a specific testing method (`this.testAwsConnection`) or use a generic handler defined in the integration manifest. If the connection test is successful, it activates the connection; otherwise, it sets the connection to an error state with a descriptive message.

<Callout title="Error Handling" variant="warning">
This method handles several potential errors:
<ul>
<li>If the provider is not found for the connection, it throws an <code>HttpException</code>.</li>
<li>If no credentials are found for the connection, it throws an <code>HttpException</code>.</li>
<li>It catches exceptions during the actual connection test (e.g., network issues to the external service, invalid credentials) and uses <code>this.connectionService.setConnectionError</code> to update the connection's status in the database, providing user-facing error messages.</li>
</ul>
</Callout>

Sources: [apps/api/src/integration-platform/controllers/connections.controller.ts:586-630](https://github.com/blade47/comp/blob/main/apps/api/src/integration-platform/controllers/connections.controller.ts#L586-L630)

### 4. `getDecryptedCredentials`

The `getDecryptedCredentials` method resides within the `CredentialVaultService`. Its purpose is to retrieve the latest encrypted credentials for a given `connectionId` and convert them into a usable, plaintext format.

This method takes the `connectionId` as input. It queries the `credentialRepository` to fetch the `latestVersion` of credentials associated with that connection. The retrieved `latestVersion` contains an `encryptedPayload`, which is a JSON object where sensitive values are stored as `EncryptedData` objects (containing `encrypted`, `iv`, `tag`, and `salt` as base64 strings). The method then iterates through this payload, calling `this.decrypt()` for each `EncryptedData` object to transform it back into its original plaintext string. Non-encrypted values are passed through directly. The final output is a `Record<string, string | string[]>` containing all decrypted credentials.

Sources: [apps/api/src/integration-platform/services/credential-vault.service.ts:241-274](https://github.com/blade47/comp/blob/main/apps/api/src/integration-platform/services/credential-vault.service.ts#L241-L274)

### 5. `decrypt`

The `decrypt` method is a private, core cryptographic function within the `CredentialVaultService`. It performs the actual decryption of a single piece of sensitive data.

This method accepts an `EncryptedData` object as input. It first calls `this.getSecretKey()` to retrieve the application's master encryption key. Using this key and the `salt` from the `EncryptedData`, it derives the specific cryptographic key required for decryption using `scryptSync`. It then initializes an `aes-256-gcm` decipher using `createDecipheriv`, sets the authentication tag (`tag`) to verify data integrity, and finally performs the decryption. The result is the original plaintext string.

Sources: [apps/api/src/integration-platform/services/credential-vault.service.ts:80-92](https://github.com/blade47/comp/blob/main/apps/api/src/integration-platform/services/credential-vault.service.ts#L80-L92)

### 6. `getSecretKey`

The `getSecretKey` method is a private helper function within the `CredentialVaultService`. Its sole responsibility is to retrieve the master encryption key required for cryptographic operations.

This method accesses the `process.env.SECRET_KEY` environment variable. This environment variable holds the critical secret key used to encrypt and decrypt all sensitive credentials stored in the vault.

<Callout title="Critical Configuration" variant="danger">
This method is a critical failure point. If the <code>SECRET_KEY</code> environment variable is not set, the method will throw an <code>Error</code>, preventing any decryption operations and effectively rendering the credential vault unusable. This highlights the importance of proper environment configuration for security.
</Callout>

Sources: [apps/api/src/integration-platform/services/credential-vault.service.ts:65-71](https://github.com/blade47/comp/blob/main/apps/api/src/integration-platform/services/credential-vault.service.ts#L65-L71)

### Sequence Diagram

```mermaid
sequenceDiagram
    participant User as User (Browser)
    participant Frontend as IntegrationPlatformTestPage
    participant BackendController as ConnectionsController
    participant CredentialVaultService as CredentialVaultService
    participant CredentialRepository as CredentialRepository
    participant Env as Environment Variables

    User->>Frontend: Clicks "Test Connection"
    Frontend->>Frontend: handleTestConnection(connId, providerSlug)
    Frontend->>BackendController: POST /integrations/connections/:id/test
    BackendController->>BackendController: getConnection(id)
    BackendController->>CredentialVaultService: getDecryptedCredentials(connectionId)
    CredentialVaultService->>CredentialRepository: findLatestByConnection(connectionId)
    CredentialRepository-->>CredentialVaultService: EncryptedData[]
    loop For each encrypted credential
        CredentialVaultService->>CredentialVaultService: decrypt(EncryptedData)
        CredentialVaultService->>CredentialVaultService: deriveKey(secret, salt)
        CredentialVaultService->>Env: getSecretKey()
        Env-->>CredentialVaultService: SECRET_KEY
        CredentialVaultService-->>CredentialVaultService: Decrypted string
    end
    CredentialVaultService-->>BackendController: Decrypted Credentials
    BackendController->>BackendController: Perform connection test (e.g., validateAwsCredentials)
    alt Test Successful
        BackendController->>BackendController: activateConnection(connectionId)
        BackendController-->>Frontend: Success message
    else Test Failed
        BackendController->>BackendController: setConnectionError(connectionId, errorMessage)
        BackendController-->>Frontend: Error message
    end
    Frontend->>Frontend: Log result
```

### Flowchart



### Key Observations

*   **Cross-Module Boundaries:** This flow demonstrates a clear separation of concerns across multiple modules and layers:
    *   **Frontend (`apps/app`):** Handles user interaction and initiates API requests.
    *   **Backend Controller (`apps/api/src/integration-platform/controllers`):** Acts as the API gateway, receiving requests and orchestrating business logic.
    *   **Backend Service (`apps/api/src/integration-platform/services`):** Contains core business logic, such as credential management and cryptographic operations.
    *   **Backend Repository (implicit in `CredentialVaultService`):** Abstracts database interactions for credential storage.
    *   **Environment Variables:** Crucial for secure configuration of the master encryption key.
*   **Potential Failure Points:**
    *   **Network failures:** Between the frontend and backend, or from the backend to external integration services.
    *   **Missing or invalid `SECRET_KEY`:** This is a critical configuration error that would prevent all decryption, leading to system-wide credential access failures.
    *   **Corrupted encrypted data:** If the stored `EncryptedData` is tampered with or malformed, decryption will fail.
    *   **Database issues:** Failure to retrieve connection or credential records.
    *   **External service unavailability:** The actual connection test to the third-party integration might fail due to the external service being down or returning errors.
    *   **Invalid credentials:** Even if decrypted successfully, the credentials might be outdated or incorrect, causing the external connection test to fail.
*   **Error Handling:**
    *   The frontend logs API call results and displays user-friendly messages.
    *   The `ConnectionsController` catches exceptions during the connection test and updates the connection's status in the database (`setConnectionError`), providing persistent feedback.
    *   The `CredentialVaultService.getSecretKey` explicitly throws an error if the `SECRET_KEY` is not set, indicating a critical deployment issue.
*   **Performance Considerations:**
    *   The cryptographic operations (`scryptSync`, `createDecipheriv`) involved in decryption are CPU-intensive. While generally fast for individual credentials, decrypting a large number of credentials concurrently could introduce latency.
    *   Database queries for connection and credential records contribute to the overall response time.
    *   The most significant performance variable is often the external API call made during the actual connection test, as its latency depends entirely on the third-party service.

## Sitemap

See the full [sitemap](https://www.doc0.dev/docs/49c89830-117b-4def-8edc-b5bcc50766e0/llms.txt) for all pages in this wiki.
