API Keys
API keys are the credential your automation (cron, CI, servers) uses to talk to BaaS. Each key belongs to one workspace, carries a fixed set of scopes, and is shown in full only once.
Generating a key in the portal (point, click, copy) is the recommended path. The examples below assume you are already authenticated with a portal key or another supported login method; see Authentication.
- Go SDK
- JS SDK
- CLI
import (
sdkclient "github.com/lighthouse-web3/baas-go-sdk/client"
sdktypes "github.com/lighthouse-web3/baas-go-sdk/types"
)
import {
BackupClient,
apiKeyPlaintext,
ScopeBackupWrite,
ScopeBackupRead,
ScopeSnapshotsRead,
} from "@lighthouse-web3/baas-js-sdk";
Install the CLI, then authenticate with a portal-created key or another supported login method:
npm install -g @lighthouse-web3/baas-js-sdk
baas auth login --api-key
Scope cheat-sheetโ
Grant only what the integration needs:
| Task | Required scope(s) |
|---|---|
| Backup | backup:write (and backup:read for dedup) |
| List / inspect snapshots | snapshots:read |
| Prune snapshots | snapshots:read + backup:write |
| Delete a snapshot | backup:write |
| Restore | restore:read, restore:write |
| Read profile / usage | user:read |
| Create / list / revoke API keys | api_keys:manage |
| Create or modify workspaces and members | workspace:manage |
A backup runner needs none of the last two โ grant api_keys:manage or workspace:manage only to keys that genuinely administer the workspace, since a key holding api_keys:manage can mint further keys.
If a call returns 403 / insufficient scope, mint a new key with the missing scope โ keys are immutable once created.
Create a keyโ
Create a dedicated key for your backup runner.
- Go SDK
- JS SDK
- CLI
import "time"
expires := time.Now().AddDate(0, 3, 0).UTC().Format(time.RFC3339) // 3 months
keyResp, err := client.CreateAPIKey(sdktypes.APIKeyCreateRequest{
Name: "nightly-postgres-backup",
WorkspaceID: workspaceID,
Scopes: []string{
sdktypes.ScopeBackupWrite,
sdktypes.ScopeBackupRead,
sdktypes.ScopeSnapshotsRead,
},
ExpiresAt: expires,
})
if err != nil {
log.Fatal(err)
}
plain := keyResp.Plaintext() // the raw lh_โฆ key; store securely, returned once
prefix := keyResp.APIKey.KeyPrefix // safe-to-log prefix
id := keyResp.APIKey.APIKeyID // id for later revoke
log.Printf("NEW API KEY (store now): %s (prefix=%s id=%s)", plain, prefix, id)
// 3 months from now
const expiresAt = new Date(Date.now() + 90 * 24 * 60 * 60 * 1000).toISOString();
const keyResp = await client.createAPIKey({
name: "nightly-postgres-backup",
workspaceId,
scopes: [ScopeBackupWrite, ScopeBackupRead, ScopeSnapshotsRead],
expiresAt,
});
const plain = apiKeyPlaintext(keyResp); // the raw lh_โฆ key; store securely, returned once
const prefix = keyResp.apiKey.keyPrefix; // safe-to-log prefix
const id = keyResp.apiKey.apiKeyId; // id for later revoke
console.log(`NEW API KEY (store now): ${plain} (prefix=${prefix} id=${id})`);
baas apikey create \
--name nightly-postgres-backup \
--scope backup:write \
--scope backup:read \
--scope snapshots:read \
--expires 2026-10-21T00:00:00Z
CreateAPIKey / createAPIKey returns an APIKeyCreateResponse. The plaintext key is keyResp.Plaintext() (Go) / apiKeyPlaintext(keyResp) (JS); the prefix, id, scopes, and expiry live on the nested keyResp.APIKey / keyResp.apiKey โ e.g. keyResp.apiKey.keyPrefix, not keyResp.keyPrefix.
Store the plaintext key in a secrets manager or environment variable (e.g.
LH_API_KEY). After this call you can only ever see its prefix again.
List API keysโ
- Go SDK
- JS SDK
- CLI
keys, err := client.ListAPIKeys()
if err != nil {
log.Fatal(err)
}
for _, k := range keys {
log.Printf("apiKeyId=%s name=%s status=%s prefix=%s", k.APIKeyID, k.Name, k.Status, k.KeyPrefix)
}
const keys = await client.listAPIKeys();
for (const k of keys) {
console.log(
`apiKeyId=${k.apiKeyId} name=${k.name} status=${k.status} prefix=${k.keyPrefix}`,
);
}
baas apikey list
Revoke an API keyโ
- Go SDK
- JS SDK
- CLI
err := client.DeleteAPIKey("add-your-api-key-id")
if err != nil {
log.Fatal(err)
}
await client.deleteAPIKey("add-your-api-key-id");
baas apikey revoke add-your-api-key-id --yes
Rotation tipsโ
- Give automation keys a hard
ExpiresAtand rotate before expiry. - One key per job/environment makes revocation blast-radius small.
- Because keys are immutable, "changing scopes" means creating a new key and revoking the old one.
For how scopes combine with workspace roles (the intersection rule), see Roles, scopes, and permissions.