Skip to main content
← Back to list
01Issue
FeatureShippedSwamp CLI
Assigneesstack72

Relationships

↑ child of #662

#674 serve-auth: client-side server credential storage

Opened by stack72 · 6/17/2026· Shipped 6/18/2026

Parent

Sub-issue of #662 (serve authentication & authorization). Layer 1, item 6.

Summary

Implement client-side storage for server credentials — the token a user receives after authenticating with a swamp serve instance. This is the client-side half of user authentication; the server-side token model is a sibling issue (#673, item 5).

Today `~/.config/swamp/auth.json` stores exactly one swamp-club credential (`src/domain/auth/auth_credentials.ts` + `src/infrastructure/persistence/auth_repository.ts`). Server credentials are a sibling aggregate: a `ServerCredential` keyed by normalized server URL, persisted to a separate file with the same precedence pattern.

What to build

Domain type

A `ServerCredential` value object in `src/domain/auth/`:

```typescript interface ServerCredential { serverUrl: string; // normalized URL (e.g. "https://swamp.acme.internal:9090") tokenName: string; // the name portion of the . token token: string; // the full . plaintext principalId: string; // the user's sub from the OAuth login displayName?: string; // the user's display name (for swamp auth whoami --server) obtainedAt: string; // ISO timestamp of when the credential was obtained } ```

Persistence

A `ServerCredentialRepository` in `src/infrastructure/persistence/`:

  • File: `~/.config/swamp/servers.json` (or `$XDG_CONFIG_HOME/swamp/servers.json`)
  • Permissions: mode `0o600` (same as `auth.json`)
  • Format: JSON object keyed by normalized server URL
  • Precedence: `SWAMP_SERVER_TOKEN` env var > `servers.json` file (same pattern as `SWAMP_API_KEY` > `auth.json`)

Repository interface

```typescript interface ServerCredentialRepository { get(serverUrl: string): Promise<ServerCredential | null>; save(credential: ServerCredential): Promise; remove(serverUrl: string): Promise; list(): Promise<ServerCredential[]>; } ```

URL normalization

Server URLs must be normalized before use as keys — strip trailing slashes, lowercase the hostname, default port handling. This prevents `https://swamp.example.com\` and `https://swamp.example.com/\` from being treated as different servers.

Environment variable override

When `SWAMP_SERVER_TOKEN` is set, it provides a token for use with `--server` commands without needing a `servers.json` entry. Follow the same pattern as `SWAMP_API_KEY` in `src/infrastructure/persistence/auth_repository.ts`.

Scope

  • `ServerCredential` type in `src/domain/auth/`
  • `ServerCredentialRepository` interface in `src/domain/auth/`
  • File-based implementation in `src/infrastructure/persistence/`
  • URL normalization utility
  • Unit tests: save/get/remove/list, file permissions, env var override, URL normalization
  • No CLI commands (the `swamp auth login --server` command that writes credentials is layer 4)

Out of scope

  • Server token model (server-side) — #673
  • `swamp auth login --server` CLI command — layer 4
  • OAuth login flow — layer 4

References

  • Existing auth credentials: `src/domain/auth/auth_credentials.ts`
  • Existing auth repository: `src/infrastructure/persistence/auth_repository.ts`
  • Config dir resolution pattern: follow how `auth.json` finds its path
02Bog Flow
OPENTRIAGEDIN PROGRESSSHIPPED+ 1 MOREASSIGNED+ 5 MOREREVIEW+ 3 MOREPR_MERGED+ 1 MORENOTIFICATION_SKIPPED

Shipped

6/18/2026, 1:10:25 PM

Click a lifecycle step above to view its details.

03Sludge Pulse
stack72 assigned stack726/18/2026, 12:19:35 AM
stack72 linked parent of #6626/19/2026, 3:06:17 PM

Sign in to post a ripple.