> ## Documentation Index
> Fetch the complete documentation index at: https://docs.gcore.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Secrets Manager

export const MethodSection = ({children}) => children ?? null;

export const MethodSwitch = ({children}) => {
  const tabs = React.Children.toArray(children).map(c => {
    if (!c || !c.props) return null;
    if (c.props.id) return c;
    const inner = c.props.children;
    if (inner && inner.props && inner.props.id) return inner;
    return null;
  }).filter(Boolean);
  const firstId = tabs.length > 0 ? tabs[0].props.id : "";
  const [active, setActive] = React.useState(firstId);
  React.useEffect(() => {
    try {
      const saved = localStorage.getItem("gcore_docs_method");
      if (saved && tabs.find(t => t.props.id === saved)) {
        setActive(saved);
      }
    } catch (_) {}
  }, []);
  React.useEffect(() => {
    try {
      document.querySelectorAll("h2[id], h3[id]").forEach(heading => {
        const visible = heading.offsetParent !== null;
        document.querySelectorAll(`a[href="#${heading.id}"]`).forEach(link => {
          if (link.closest("h1,h2,h3,h4,h5,h6")) return;
          const li = link.closest("li");
          if (li) li.style.display = visible ? "" : "none";
        });
      });
    } catch (_) {}
    window.dispatchEvent(new Event("scroll"));
  }, [active]);
  const handleClick = id => {
    setActive(id);
    try {
      localStorage.setItem("gcore_docs_method", id);
    } catch (_) {}
  };
  return <div>
      <div className="not-prose flex gap-0 border-b border-zinc-200 dark:border-zinc-800 mb-8 mt-2" role="tablist">
        {tabs.map(tab => {
    const isActive = active === tab.props.id;
    return <button key={tab.props.id} role="tab" aria-selected={isActive} onClick={() => handleClick(tab.props.id)} className={["px-4 py-2 text-sm font-medium border-b-2 -mb-px transition-colors cursor-pointer", isActive ? "border-primary text-primary" : "border-transparent text-zinc-500 hover:text-zinc-800 dark:hover:text-zinc-200"].join(" ")}>
              {tab.props.label}
            </button>;
  })}
      </div>

      {tabs.map(tab => <div key={tab.props.id} style={{
    display: active === tab.props.id ? "" : "none"
  }}>
          {tab.props.children}
        </div>)}
    </div>;
};

<MethodSwitch>
  <MethodSection id="portal" label="Customer Portal">
    Secrets Manager stores encrypted values that FastEdge applications can read at runtime. Each secret has a name, an optional description, and one or more slots — each slot holds an independently encrypted value. Use slot `0` for a regular single-value secret. Multiple slots are used for rotation scenarios where different values become active at different times.

    ## Create a secret

    1. In the [Gcore Customer Portal](https://portal.gcore.com), navigate to **FastEdge** > **Secrets Manager**.

    2. Click **Add secret**.

    <Frame>
      <img src="https://mintcdn.com/gcore/MFAXqa6tFHU8UZIW/images/docs/fastedge/secrets-manager/manage-secrets/secrets-list.png?fit=max&auto=format&n=MFAXqa6tFHU8UZIW&q=85&s=b980bdafaefed27c1e2fb8f4831325d7" alt="Secrets Manager page with the Add secret button" width="1024" height="452" data-path="images/docs/fastedge/secrets-manager/manage-secrets/secrets-list.png" />
    </Frame>

    3. Enter a **Name** and an optional **Description**.

    4. In the **Slots** section, enter a **Slot index** and the secret value in the **Value** field. Use `0` for a single-value secret.

    5. Click **Encrypt**. The field shows "Encrypted Value" to confirm the value was encrypted.

    <Frame>
      <img src="https://mintcdn.com/gcore/MFAXqa6tFHU8UZIW/images/docs/fastedge/secrets-manager/manage-secrets/create-secret-encrypted.png?fit=max&auto=format&n=MFAXqa6tFHU8UZIW&q=85&s=e90807968232c0ccd30653a74bcaf8f9" alt="Create secret form with name, description, and slot value encrypted" width="1024" height="517" data-path="images/docs/fastedge/secrets-manager/manage-secrets/create-secret-encrypted.png" />
    </Frame>

    6. Click **Save changes**.

    <Warning>
      Once saved, the original value cannot be viewed — only replaced. Encrypted values are stored separately from application data to protect against unauthorized access.
    </Warning>

    ## Edit a secret

    1. Navigate to **FastEdge** > **Secrets Manager**.

    2. Click the secret name to open the edit form.

    <Frame>
      <img src="https://mintcdn.com/gcore/MFAXqa6tFHU8UZIW/images/docs/fastedge/secrets-manager/manage-secrets/secrets-list-with-item.png?fit=max&auto=format&n=MFAXqa6tFHU8UZIW&q=85&s=c678d32f91c24e93c60bdff6b07fb64a" alt="Secrets Manager list showing a secret entry" width="1024" height="338" data-path="images/docs/fastedge/secrets-manager/manage-secrets/secrets-list-with-item.png" />
    </Frame>

    3. To replace an encrypted value, click the pencil icon next to the **Value** field, enter the new value, and click **Encrypt**.

    <Frame>
      <img src="https://mintcdn.com/gcore/MFAXqa6tFHU8UZIW/images/docs/fastedge/secrets-manager/manage-secrets/edit-secret-form.png?fit=max&auto=format&n=MFAXqa6tFHU8UZIW&q=85&s=b7559d25c84dbee86d38b26d84f634f3" alt="Edit secret form with the pencil icon next to the encrypted value field" width="1024" height="298" data-path="images/docs/fastedge/secrets-manager/manage-secrets/edit-secret-form.png" />
    </Frame>

    4. Click **Save changes**.

    ## Delete a secret

    1. Navigate to **FastEdge** > **Secrets Manager**.

    2. Click the three-dot icon (**...**) next to the secret and select **Delete**.

    <Frame>
      <img src="https://mintcdn.com/gcore/MFAXqa6tFHU8UZIW/images/docs/fastedge/secrets-manager/manage-secrets/delete-secret-menu.png?fit=max&auto=format&n=MFAXqa6tFHU8UZIW&q=85&s=044f7d7482b7ea0b43c37eb2d5283373" alt="Secrets Manager list with the three-dot menu showing Edit and Delete options" width="1024" height="296" data-path="images/docs/fastedge/secrets-manager/manage-secrets/delete-secret-menu.png" />
    </Frame>

    3. Click **Yes, delete** to confirm.

    <Warning>
      A secret assigned to an application cannot be deleted — remove it from the application first. Deleted secrets cannot be restored.
    </Warning>

    ## Secrets in applications

    Creating a secret only stores the encrypted value. To make it available to an application, link it from the application's **Secrets** tab in [manage apps](/fastedge/manage-apps#secrets). The application reads the value at runtime using the secret name and slot index via the [JavaScript SDK](https://g-core.github.io/FastEdge-sdk-js/reference/fastedge/secret/get-secret/) or [Rust SDK](https://docs.rs/fastedge/latest/fastedge/secret/index.html).
  </MethodSection>

  <MethodSection id="api" label="REST API">
    Secrets Manager stores encrypted values that FastEdge applications read at runtime. The API covers the full secret lifecycle: create, read, update, and delete. Each secret contains one or more slots — a slot holds an encrypted value and a numeric identifier. Use slot `0` for single-value secrets; multiple slots support time-based rotation using Unix timestamps as identifiers.

    <p>All requests authenticate with an [API token](/account-settings/api-tokens). Set it as an environment variable before running the examples:</p>

    ```bash theme={null}
    export GCORE_API_KEY="{YOUR_API_KEY}"
    ```

    ## Create a secret

    ```bash theme={null}
    curl -X POST https://api.gcore.com/fastedge/v1/secrets \
      -H "Authorization: APIKey $GCORE_API_KEY" \
      -H "Content-Type: application/json" \
      -d '{
        "name": "my-app-secret",
        "comment": "API key for external service",
        "secret_slots": [
          {
            "slot": 0,
            "value": "your-secret-value"
          }
        ]
      }'
    ```

    The response returns the created secret with its assigned ID:

    ```json theme={null}
    {
      "id": 638,
      "name": "my-app-secret",
      "comment": "API key for external service",
      "secret_slots": [
        {
          "slot": 0,
          "checksum": "03a0986e7619f1d45d12369a1a58d2bbfc3e9f8aea9c5fe84b86087ff8941abb"
        }
      ]
    }
    ```

    The `checksum` field identifies the stored encrypted value. The original value is never returned.

    ## List secrets

    ```bash theme={null}
    curl https://api.gcore.com/fastedge/v1/secrets \
      -H "Authorization: APIKey $GCORE_API_KEY"
    ```

    Optional query parameters:

    | Parameter     | Type    | Description                                          |
    | ------------- | ------- | ---------------------------------------------------- |
    | `app_id`      | integer | Filter secrets assigned to the specified application |
    | `secret_name` | string  | Filter by exact secret name                          |

    Response:

    ```json theme={null}
    {
      "count": 2,
      "secrets": [
        {
          "id": 636,
          "name": "docs-audit-secret",
          "comment": "",
          "app_count": 0
        },
        {
          "id": 638,
          "name": "my-app-secret",
          "comment": "API key for external service",
          "app_count": 1
        }
      ]
    }
    ```

    ## Get a secret

    ```bash theme={null}
    curl https://api.gcore.com/fastedge/v1/secrets/SECRET_ID \
      -H "Authorization: APIKey $GCORE_API_KEY"
    ```

    Response includes the slot list with checksums:

    ```json theme={null}
    {
      "name": "my-app-secret",
      "comment": "API key for external service",
      "app_count": 1,
      "secret_slots": [
        {
          "slot": 0,
          "checksum": "03a0986e7619f1d45d12369a1a58d2bbfc3e9f8aea9c5fe84b86087ff8941abb"
        }
      ]
    }
    ```

    ## Update a secret

    Use `PATCH` to update the name, description, or slot values. Only the fields included in the request body are changed.

    ```bash theme={null}
    curl -X PATCH https://api.gcore.com/fastedge/v1/secrets/SECRET_ID \
      -H "Authorization: APIKey $GCORE_API_KEY" \
      -H "Content-Type: application/json" \
      -d '{
        "comment": "Updated description",
        "secret_slots": [
          {
            "slot": 0,
            "value": "new-secret-value"
          }
        ]
      }'
    ```

    The response returns the full updated secret object, including the new checksum for the updated slot.

    ## Delete a secret

    ```bash theme={null}
    curl -X DELETE "https://api.gcore.com/fastedge/v1/secrets/SECRET_ID?force=true" \
      -H "Authorization: APIKey $GCORE_API_KEY"
    ```

    A successful response returns HTTP 204 with no body.

    <Warning>
      The `force=true` parameter is required when the secret has encrypted slots. Without it, the request returns 400. If the secret is assigned to an application, `force=true` also removes it from all assigned applications before deletion.
    </Warning>
  </MethodSection>
</MethodSwitch>
