# Secrets

> The SDK methods that store secrets and choose which sandboxes may use them, in TypeScript and Python.

Source: https://useshards.com/docs/reference/sdks/secrets/

## shard.secrets.set

Store a secret, or replace its value.

**TypeScript**

```ts
shard.secrets.set(name: string, options: { value: string; destinations?: string[]; placeholder?: string }): Promise<SecretInfo>
```

**Python**

```python
shard.secrets.set(name, *, value, destinations=None, placeholder=None) -> SecretInfo
```

**Examples**

**TypeScript**

```ts
const value = process.env.API_TOKEN;
if (!value) throw new Error("set API_TOKEN");
await shard.secrets.set("API_TOKEN", { value, destinations: ["api.example.com"] });
```

**Python**

```python
import os

shard.secrets.set("API_TOKEN", value=os.environ["API_TOKEN"], destinations=["api.example.com"])
```

**Arguments**

| Argument | Description |
| --- | --- |
| `name` | secret name; upper-case letters, digits and underscores |

**Options**

| TypeScript | Python | Description |
| --- | --- | --- |
| `value` | `value` | secret value |
| `destinations` | `destinations` | approved destinations; the first set of a name needs one, and a later set without them keeps the old ones |
| `placeholder` | `placeholder` | value visible inside the sandbox; `mock-NAME` by default |

The sandbox receives the placeholder instead of the secret value. In HTTPS request headers sent to approved destinations, shard puts the value in its place. The result never holds the value, and the SDK never reads one back.

Set an existing secret again to update its value. Custom placeholders can contain letters, digits, underscores, hyphens and dots. Read the value from the environment or a secret store, never from source code.

## shard.secrets.list

List secrets without their values.

**TypeScript**

```ts
shard.secrets.list(): Promise<{ secrets: SecretInfo[]; warnings: string[] }>
```

**Python**

```python
shard.secrets.list() -> SecretList  # SecretList(secrets, warnings)
```

**Examples**

**TypeScript**

```ts
const { secrets } = await shard.secrets.list();
for (const secret of secrets) console.log(secret.name, secret.destinations);
```

**Python**

```python
for secret in shard.secrets.list().secrets:
    print(secret.name, secret.destinations)
```

A `SecretInfo` holds `name`, `destinations`, `placeholder` and the update time. The warnings name entries the daemon could not read.

## shard.secrets.remove

Delete a stored secret.

**TypeScript**

```ts
shard.secrets.remove(name: string, options?: { force?: boolean }): Promise<void>
```

**Python**

```python
shard.secrets.remove(name, *, force=False) -> None
```

**Examples**

**TypeScript**

```ts
await shard.secrets.remove("API_TOKEN");
```

**Python**

```python
shard.secrets.remove("API_TOKEN")
```

**Options**

| TypeScript | Python | Description |
| --- | --- | --- |
| `force` | `force` | delete the secret even if a sandbox uses it |

With `force`, a sandbox that held the secret keeps the grant, but its placeholder no longer gets a value.

## shard.secrets.grant

Let a sandbox use a stored secret.

**TypeScript**

```ts
shard.secrets.grant(sandbox: SandboxRef, name: string): Promise<SandboxInfo>
```

**Python**

```python
shard.secrets.grant(sandbox, name) -> SandboxInfo
```

**Examples**

**TypeScript**

```ts
await web.stop();
await shard.secrets.grant(web, "API_TOKEN");
await web.start();
```

**Python**

```python
web.stop()
shard.secrets.grant(web, "API_TOKEN")
web.start()
```

**Arguments**

| Argument | Description |
| --- | --- |
| `sandbox` | a `Sandbox`, or its ID, ID prefix or name |
| `name` | secret name |

The sandbox must be created or stopped. Its commands receive the secret's placeholder as `$NAME`. To grant a secret at create time, pass `secrets` to [`shard.create`](https://useshards.com/docs/reference/sdks/sandboxes/#shardcreate).

## shard.secrets.ungrant

Remove a sandbox's access to a secret.

**TypeScript**

```ts
shard.secrets.ungrant(sandbox: SandboxRef, name: string): Promise<SandboxInfo>
```

**Python**

```python
shard.secrets.ungrant(sandbox, name) -> SandboxInfo
```

**Examples**

**TypeScript**

```ts
await shard.secrets.ungrant(web, "API_TOKEN");
```

**Python**

```python
shard.secrets.ungrant(web, "API_TOKEN")
```

The sandbox must be created or stopped.

For the whole flow, see [Credential brokering](https://useshards.com/docs/essentials/credential-brokering/).
