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

# Forge 시크릿 사용하기

> Python 또는 TypeScript로 서버리스 용량의 샌드박스에 Forge 팀 시크릿을 주입합니다.

Forge Secret Manager를 사용하면 서버리스 용량에서 실행되는 샌드박스 안에서 API 토큰과 기타 사용자 인증 정보를 사용할 수 있습니다. 애플리케이션이 Sandboxes API에 시크릿 이름을 전달하면, API는 샌드박스를 생성할 때 Forge 팀에서 해당 값을 조회해 환경 변수로 주입합니다.

<h2 id="before-you-begin">
  시작하기 전에
</h2>

Forge 시크릿 주입을 사용하려면 Forge API 키로 인증된 샌드박스가 필요합니다. 이 기능은 서버리스 샌드박스에서 사용할 수 있지만, 자체 CoreWeave Kubernetes Service(CKS) 클러스터의 샌드박스에서는 사용할 수 없습니다. CKS 배치에는 CoreWeave API 액세스 토큰이 사용됩니다. 이 토큰을 별도의 Forge API 키와 함께 사용하여 CKS 샌드박스의 시크릿을 가져올 수는 없습니다.

| 샌드박스 배치 | 샌드박스 사용자 인증 정보 | Forge 시크릿 주입 |
| - | - | - |
| 서버리스 | Forge API 키 | 지원됨. `wandb` 저장소를 사용하세요. |
| 서버리스 | CoreWeave API 액세스 토큰 | 지원되지 않음. |
| 자체 CKS 클러스터 | CoreWeave API 액세스 토큰 | 지원되지 않음. `FORGE_API_KEY`를 추가해도 활성화되지 않습니다. |

예시를 따라 하려면 다음이 필요합니다.

* [서버리스 샌드박스 액세스](/ko/products/sandboxes/get-started) 권한이 있는 Forge SaaS(Software as a Service) 계정
* Forge 팀의 Secret Manager에 저장된 `HF_TOKEN`이라는 시크릿. 이 시크릿이 없으면 Forge Admin에게 [시크릿 추가](/ko/products/wandb/platform/secrets#add-a-secret)를 요청하세요.
* 해당 팀에 액세스할 수 있는 Forge API 키

샌드박스를 생성하는 프로세스의 환경에 `FORGE_API_KEY`를 설정하세요. `[FORGE-API-KEY]`는 본인의 Forge API 키로 바꾸세요.

```bash theme={"system"}
export FORGE_API_KEY="[FORGE-API-KEY]"
```

`FORGE_TEAM`을 설정하지 않으면 예시에서는 API 키의 기본 팀을 사용합니다. 시크릿이 다른 팀에 속해 있다면 `FORGE_TEAM`을 해당 팀으로 설정하세요. `[FORGE-TEAM]`을 팀 이름으로 바꾸세요.

```bash theme={"system"}
export FORGE_TEAM="[FORGE-TEAM]"
```

예시에서는 이러한 변수를 클라이언트에 명시적으로 전달합니다. SDK는 `FORGE_API_KEY`나 `FORGE_TEAM`을 자동으로 감지하지 않습니다.

사용하는 언어에 맞는 클라이언트를 설치하세요.

<Tabs>
  <Tab title="Python">
    Python 3.11 이상을 사용하고, 필요하면 [`uv`를 설치](https://docs.astral.sh/uv/getting-started/installation/)하세요. Python 환경에 클라이언트를 설치하세요.

    ```bash theme={"system"}
    uv pip install 'cwsandbox>=1.14.2'
    ```
  </Tab>

  <Tab title="TypeScript">
    Node.js 22 이상을 사용하세요. TypeScript 클라이언트와 예시 실행에 필요한 `tsx`를 설치하세요.

    ```bash theme={"system"}
    npm install @coreweave/cwsandbox
    npm install --save-dev tsx
    ```

    실행할 TypeScript 예시를 `secrets.mts`로 저장한 다음 `npx tsx secrets.mts`를 실행하세요.
  </Tab>
</Tabs>

<h2 id="inject-a-secret">
  시크릿 주입
</h2>

Python에서는 `store="wandb"`를, TypeScript에서는 `store: "wandb"`를 사용하세요. 이 저장소는 인증된 Forge 팀의 시크릿을 해석합니다. 이 플로우에서는 조직 시크릿 저장소를 등록할 필요가 없습니다.

다음 예시는 `HF_TOKEN`을 주입한 뒤, 값을 출력하지 않고 존재 여부만 확인합니다. 샌드박스에서 환경 변수 이름은 기본적으로 시크릿 이름과 같습니다.

<Tabs>
  <Tab title="Python">
    `AuthHeaders`를 통해 Forge API 키와 팀(선택 사항)을 전달하세요:

    ```python theme={"system"}
    import os
    from cwsandbox import AuthHeaders, Sandbox, Secret

    forge_auth = AuthHeaders(
        headers={
            "x-wandb-api-key": os.environ["FORGE_API_KEY"],
            **({"x-entity-id": os.environ["FORGE_TEAM"]} if os.environ.get("FORGE_TEAM") else {}),
        },
        strategy="wandb_api_key",
    )

    with Sandbox.run(
      auth=forge_auth,
      placement_mode="serverless",
      container_image="python:3.11",
      resources={"cpu": "1", "memory": "1Gi"},
      secrets=[Secret(store="wandb", name="HF_TOKEN")],
    ) as sandbox:
      result = sandbox.exec([
        "python", "-c",
        "import os; assert os.environ.get('HF_TOKEN'); print('Secret is available')",
      ]).result()
      print(result.stdout)
    ```
  </Tab>

  <Tab title="TypeScript">
    Forge 진입점에서 클라이언트를 임포트하세요. `runnerIds`를 생략하면 클라이언트는 서버리스 배치를 사용합니다:

    ```typescript theme={"system"}
    import { createSandboxClient } from "@coreweave/cwsandbox/wandb";

    const client = createSandboxClient({
      apiKey: process.env.FORGE_API_KEY,
      entity: process.env.FORGE_TEAM,
    });

    const result = await client.withSandbox(
      async (sandbox) => sandbox.commands.run([
        "python", "-c",
        "import os; assert os.environ.get('HF_TOKEN'); print('Secret is available')",
      ]),
      {
        containerImage: "python:3.11",
        resources: { cpu: "1", memory: "1Gi" },
        secrets: [{ store: "wandb", name: "HF_TOKEN" }],
      },
    );

    console.log(result.stdout);
    ```
  </Tab>
</Tabs>

두 예시 모두 `Secret is available`을 출력하고, 오퍼레이션이 종료되면 샌드박스를 중지합니다. 샌드박스 내부에서 실행되는 코드는 `HF_TOKEN`에서 값을 읽을 수 있습니다.

`secrets`에는 시크릿 값이 아닌 이름을 전달하세요. 값은 서버가 해석합니다. 값을 출력하거나 로그에 기록하지 마십시오.

<h2 id="secret-reference-fields">
  시크릿 참조 필드
</h2>

Python `Secret` 또는 TypeScript `secrets` 항목에서 이 필드를 사용하세요:

| Python 필드 | TypeScript 필드 | Required | 설명 |
| - | - | - | - |
| `store` | `store` | Yes | 시크릿 저장소 이름. Forge Secret Manager의 경우 `wandb`를 사용하세요. |
| `name` | `name` | Yes | 선택한 Forge 팀의 Secret Manager에 있는 시크릿의 이름. |
| `field` | `field` | No | 값이 JSON 객체인 시크릿에서 선택할 최상위 키. 전체 시크릿 값을 주입하려면 생략하세요. |
| `env_var` | `envVar` | No | 값을 받는 환경 변수. 기본값은 `name`입니다. |

<h2 id="use-a-custom-environment-variable-name">
  맞춤형 환경 변수 이름 사용
</h2>

시크릿을 받을 환경 변수를 선택하려면 Python에서 `env_var`를, TypeScript에서 `envVar`를 설정하세요. 다음 예시는 `HF_TOKEN` 시크릿을 `HUGGINGFACE_TOKEN`으로 노출합니다:

<Tabs>
  <Tab title="Python">
    ```python theme={"system"}
    import os
    from cwsandbox import AuthHeaders, Sandbox, Secret

    forge_auth = AuthHeaders(
        headers={
            "x-wandb-api-key": os.environ["FORGE_API_KEY"],
            **({"x-entity-id": os.environ["FORGE_TEAM"]} if os.environ.get("FORGE_TEAM") else {}),
        },
        strategy="wandb_api_key",
    )

    with Sandbox.run(
      auth=forge_auth,
      placement_mode="serverless",
      container_image="python:3.11",
      secrets=[Secret(
        store="wandb",
        name="HF_TOKEN",
        env_var="HUGGINGFACE_TOKEN",
      )],
    ) as sandbox:
      result = sandbox.exec([
        "python", "-c",
        "import os; assert os.environ.get('HUGGINGFACE_TOKEN'); print('Secret is available')",
      ]).result()
      print(result.stdout)
    ```
  </Tab>

  <Tab title="TypeScript">
    ```typescript theme={"system"}
    import { createSandboxClient } from "@coreweave/cwsandbox/wandb";

    const client = createSandboxClient({
      apiKey: process.env.FORGE_API_KEY,
      entity: process.env.FORGE_TEAM,
    });

    const result = await client.withSandbox(
      async (sandbox) => sandbox.commands.run([
        "python", "-c",
        "import os; assert os.environ.get('HUGGINGFACE_TOKEN'); print('Secret is available')",
      ]),
      {
        containerImage: "python:3.11",
        secrets: [{
          store: "wandb",
          name: "HF_TOKEN",
          envVar: "HUGGINGFACE_TOKEN",
        }],
      },
    );

    console.log(result.stdout);
    ```
  </Tab>
</Tabs>

두 예시 모두 `HUGGINGFACE_TOKEN`이 존재하는지 확인한 후 `Secret is available`을 출력합니다.

<h2 id="select-a-field-from-a-structured-secret">
  구조화된 시크릿에서 필드 선택
</h2>

JSON 객체에서 하나의 값을 주입하려면 `field`를 해당 최상위 키로 설정하세요. 중첩된 경로는 지원되지 않습니다. JSON 문자열의 경우, 주입된 값에는 JSON 따옴표가 없습니다.

이 예제에서는 값이 `{"password":"[DB-PASSWORD]"}`와 같은 JSON 객체인 `DB_CREDENTIALS`라는 팀 시크릿을 추가하세요. 시크릿을 저장하기 전에 `[DB-PASSWORD]`를 비밀번호로 교체하세요. 예시에서는 `password` 필드를 `DB_PASSWORD`에 주입합니다:

<Tabs>
  <Tab title="Python">
    ```python theme={"system"}
    import os
    from cwsandbox import AuthHeaders, Sandbox, Secret

    forge_auth = AuthHeaders(
        headers={
            "x-wandb-api-key": os.environ["FORGE_API_KEY"],
            **({"x-entity-id": os.environ["FORGE_TEAM"]} if os.environ.get("FORGE_TEAM") else {}),
        },
        strategy="wandb_api_key",
    )

    with Sandbox.run(
      auth=forge_auth,
      placement_mode="serverless",
      container_image="python:3.11",
      secrets=[Secret(
        store="wandb",
        name="DB_CREDENTIALS",
        field="password",
        env_var="DB_PASSWORD",
      )],
    ) as sandbox:
      result = sandbox.exec([
        "python", "-c",
        "import os; assert os.environ.get('DB_PASSWORD'); print('Secret is available')",
      ]).result()
      print(result.stdout)
    ```
  </Tab>

  <Tab title="TypeScript">
    ```typescript theme={"system"}
    import { createSandboxClient } from "@coreweave/cwsandbox/wandb";

    const client = createSandboxClient({
      apiKey: process.env.FORGE_API_KEY,
      entity: process.env.FORGE_TEAM,
    });

    const result = await client.withSandbox(
      async (sandbox) => sandbox.commands.run([
        "python", "-c",
        "import os; assert os.environ.get('DB_PASSWORD'); print('Secret is available')",
      ]),
      {
        containerImage: "python:3.11",
        secrets: [{
          store: "wandb",
          name: "DB_CREDENTIALS",
          field: "password",
          envVar: "DB_PASSWORD",
        }],
      },
    );

    console.log(result.stdout);
    ```
  </Tab>
</Tabs>

두 예시 모두 비밀번호를 출력하지 않고 `Secret is available`을 출력합니다. 시크릿이 JSON 객체가 아니거나, 키가 존재하지 않거나, 값이 `null`이면 필드 선택이 실패합니다.

<h2 id="reuse-secret-references">
  시크릿 참조 재사용
</h2>

Python 세션의 경우, 공유 시크릿 참조를 `SandboxDefaults`에 넣으세요. TypeScript의 경우, 샌드박스를 생성할 때 `secrets` 배열을 재사용하세요:

<Tabs>
  <Tab title="Python">
    ```python theme={"system"}
    import os
    from cwsandbox import AuthHeaders, SandboxDefaults, Secret, Session

    forge_auth = AuthHeaders(
        headers={
            "x-wandb-api-key": os.environ["FORGE_API_KEY"],
            **({"x-entity-id": os.environ["FORGE_TEAM"]} if os.environ.get("FORGE_TEAM") else {}),
        },
        strategy="wandb_api_key",
    )

    defaults = SandboxDefaults(
      auth=forge_auth,
      placement_mode="serverless",
      secrets=(Secret(store="wandb", name="HF_TOKEN"),),
    )

    with Session(defaults) as session:
      sandbox = session.sandbox()
      result = sandbox.exec([
        "python", "-c",
        "import os; assert os.environ.get('HF_TOKEN'); print('Secret is available')",
      ]).result()
      print(result.stdout)
    ```

    Python 클라이언트는 세션 기본값을 샌드박스별 `secrets`와 병합하고 정확한 중복을 무시합니다. 서로 다른 레퍼런스가 동일한 환경 변수를 대상으로 하는 경우, 클라이언트는 샌드박스를 생성하기 전에 `ValueError`를 발생시킵니다. Python 유형 시그니처는 [시크릿 참조](/ko/products/sandboxes/client/ref/configuration/secret)를 참조하세요.
  </Tab>

  <Tab title="TypeScript">
    ```typescript theme={"system"}
    import { createSandboxClient } from "@coreweave/cwsandbox/wandb";

    const client = createSandboxClient({
      apiKey: process.env.FORGE_API_KEY,
      entity: process.env.FORGE_TEAM,
    });
    const secrets = [{ store: "wandb", name: "HF_TOKEN" }];

    const result = await client.withSandbox(
      async (sandbox) => sandbox.commands.run([
        "python", "-c",
        "import os; assert os.environ.get('HF_TOKEN'); print('Secret is available')",
      ]),
      { containerImage: "python:3.11", secrets },
    );

    console.log(result.stdout);
    ```
  </Tab>
</Tabs>

<h2 id="troubleshoot-secret-injection">
  시크릿 주입 문제 해결
</h2>

시크릿 참조로 샌드박스를 시작하지 못하면 오류 메시지를 통해 인증, 선택한 팀, 배치를 확인하세요.

| 오류 메시지 | 확인할 사항 |
| - | - |
| `secret store "wandb" not found` | 클라이언트에서 CoreWeave 인증을 선택했는지 확인하세요. 서버리스 배치의 경우 예시와 같이 Python에서는 `AuthHeaders`를 통해, TypeScript에서는 `@coreweave/cwsandbox/wandb`의 `createSandboxClient`를 통해 Forge 사용자 인증 정보를 전달하세요. `FORGE_API_KEY`만 설정해도 CoreWeave 인증을 사용하는 클라이언트가 Forge 인증으로 전환되지는 않습니다. 저장소를 등록할 필요는 없습니다. |
| `one or more W&B secrets not found` | 시크릿 이름과 선택한 Forge 팀을 확인하세요. 시크릿이 API 키의 기본 entity가 아닌 다른 팀에 속해 있다면 `FORGE_TEAM`을 설정하고, Forge 계정으로 해당 시크릿에 액세스할 수 있는지 확인하세요. |
| `entity not found` | `FORGE_TEAM`에 오타가 없는지 확인하고, 팀이 존재하며 Forge 계정으로 해당 팀에 액세스할 수 있는지 확인하세요. |
| `no eligible runner is available on this replica right now; retry shortly` | Forge 인증으로 CKS 러너를 선택했다면 지원되지 않는 조합입니다. 재시도해도 사용할 수 없습니다. 시크릿 주입에는 서버리스 배치와 Forge 인증을 사용하세요. 서버리스 요청에서 이 오류는 러너를 일시적으로 사용할 수 없음을 나타낼 수 있습니다. |

CoreWeave API 액세스 토큰과 Forge API 키를 모두 설정한 경우에도 CKS 배치에서는 Forge 시크릿 주입을 사용할 수 없습니다.
