Released v1
This commit is contained in:
@@ -0,0 +1,2 @@
|
||||
schema: spec-driven
|
||||
created: 2026-02-11
|
||||
@@ -0,0 +1,43 @@
|
||||
## Context
|
||||
|
||||
pcli currently authenticates to the Planka API using two mechanisms:
|
||||
1. **Bearer token** — `Authorization: Bearer <jwt>` header on every request
|
||||
2. **OIDC mode** — Bearer token + `httpOnlyToken` cookie sent together
|
||||
|
||||
Both rely on session-based JWTs obtained externally. The `Client` struct carries both `Token` and `HttpOnlyToken` fields, and the `Do()` method conditionally attaches the cookie. The CLI exposes `PLANKA_TOKEN`, `--token`, `PLANKA_HTTP_TOKEN`, and `--http-token`.
|
||||
|
||||
Planka now supports user-level API keys authenticated via the `x-api-key` header. This is simpler, long-lived, and eliminates the dual-mode complexity.
|
||||
|
||||
## Goals / Non-Goals
|
||||
|
||||
**Goals:**
|
||||
- Replace all authentication with a single `x-api-key` header
|
||||
- Simplify the `Client` struct and constructor
|
||||
- Rename env var to `PLANKA_API_KEY` and flag to `--api-key`
|
||||
- Remove all OIDC/httpOnlyToken support
|
||||
|
||||
**Non-Goals:**
|
||||
- Supporting both old and new auth simultaneously (no transition period)
|
||||
- API key management (creation/rotation/deletion) via pcli
|
||||
- Any changes to API endpoint paths or request/response formats
|
||||
|
||||
## Decisions
|
||||
|
||||
### Decision 1: Use `x-api-key` header directly
|
||||
**Choice**: Set `x-api-key: <key>` header instead of `Authorization: Bearer <key>`.
|
||||
**Rationale**: This is the header format documented by Planka for API key auth. Using the standard Planka format ensures compatibility.
|
||||
**Alternatives considered**: Using `Authorization: Bearer <api-key>` — rejected because Planka's API key auth specifically uses the `x-api-key` header.
|
||||
|
||||
### Decision 2: Clean break, no backward compatibility
|
||||
**Choice**: Remove `PLANKA_TOKEN` and `--token` entirely, replace with `PLANKA_API_KEY` and `--api-key`.
|
||||
**Rationale**: Supporting both old and new env vars adds complexity for no real benefit. This is a CLI tool where users control their own environment. A clean break with clear error messages is simpler.
|
||||
**Alternatives considered**: Supporting both `PLANKA_TOKEN` and `PLANKA_API_KEY` with deprecation warnings — rejected as unnecessary complexity for a CLI tool.
|
||||
|
||||
### Decision 3: Single field on Client struct
|
||||
**Choice**: Replace `Token` + `HttpOnlyToken` fields with a single `APIKey` field.
|
||||
**Rationale**: API key auth has no secondary credential. One field, one header, one code path.
|
||||
|
||||
## Risks / Trade-offs
|
||||
|
||||
- **Breaking change for all users** → Mitigated by clear naming (`PLANKA_API_KEY`) and error message that tells users what's needed. Users must generate an API key in Planka before upgrading.
|
||||
- **API key shown only once at creation** → Not a pcli concern, but worth noting in README that users should store their key securely.
|
||||
@@ -0,0 +1,31 @@
|
||||
## Why
|
||||
|
||||
Planka now supports user-level API key authentication. The current pcli authentication uses session-based JWT tokens (via `Authorization: Bearer <token>`) with an optional OIDC httpOnlyToken cookie path. API keys are simpler, long-lived, and eliminate the need for multiple auth modes. Replacing the current auth with API key auth simplifies both the codebase and the user experience.
|
||||
|
||||
## What Changes
|
||||
|
||||
- **BREAKING**: Replace `Authorization: Bearer <token>` header with `x-api-key: <key>` header on all API requests
|
||||
- **BREAKING**: Rename environment variable `PLANKA_TOKEN` → `PLANKA_API_KEY`
|
||||
- **BREAKING**: Rename CLI flag `--token` → `--api-key`
|
||||
- Remove `PLANKA_HTTP_TOKEN` environment variable support
|
||||
- Remove `--http-token` CLI flag
|
||||
- Remove `HttpOnlyToken` field from the `Client` struct and all OIDC cookie logic
|
||||
- Simplify `NewClient` constructor to accept only base URL, API key, and logger
|
||||
|
||||
## Capabilities
|
||||
|
||||
### New Capabilities
|
||||
|
||||
(none)
|
||||
|
||||
### Modified Capabilities
|
||||
|
||||
- `api-client`: Authentication header changes from `Authorization: Bearer` to `x-api-key`. Client struct drops `HttpOnlyToken` field. `NewClient` signature simplifies. OIDC cookie logic removed.
|
||||
- `cli-commands`: Root command global flags change: `--token` → `--api-key`, `--http-token` removed. Environment variable changes: `PLANKA_TOKEN` → `PLANKA_API_KEY`, `PLANKA_HTTP_TOKEN` removed.
|
||||
|
||||
## Impact
|
||||
|
||||
- **Code**: `client/client.go` (struct, constructor, `Do()` method), `cmd/root.go` (flags, env vars, client init)
|
||||
- **Users**: All existing users must update their environment variables and any scripts from `PLANKA_TOKEN` to `PLANKA_API_KEY` and generate an API key in Planka
|
||||
- **Dependencies**: No dependency changes
|
||||
- **API**: No Planka API endpoint changes — only the authentication mechanism used by pcli changes
|
||||
+35
@@ -0,0 +1,35 @@
|
||||
## MODIFIED Requirements
|
||||
|
||||
### Requirement: Base HTTP client
|
||||
The system SHALL provide a base HTTP client that sends requests to the Planka API. The client SHALL construct URLs by joining the configured base URL with the API path. The client SHALL attach an `x-api-key: <key>` header to every request. The client SHALL send and receive JSON (`Content-Type: application/json`). The client SHALL accept a `*slog.Logger` and log every request at DEBUG level with method, path, status code, and duration. The client SHALL log errors at WARN level.
|
||||
|
||||
#### Scenario: Successful API request
|
||||
- **WHEN** the client sends a request to a valid endpoint
|
||||
- **THEN** the response body SHALL be returned as parsed JSON
|
||||
- **AND** the request SHALL include the `x-api-key` header
|
||||
- **AND** a DEBUG log entry SHALL be emitted with method, path, status, and duration
|
||||
|
||||
#### Scenario: API returns error status
|
||||
- **WHEN** the API responds with a 4xx or 5xx status code
|
||||
- **THEN** the client SHALL return an `APIError` containing the HTTP status code and response message
|
||||
- **AND** a WARN log entry SHALL be emitted
|
||||
|
||||
#### Scenario: Network failure
|
||||
- **WHEN** the HTTP request fails due to a network error (connection refused, timeout, DNS failure)
|
||||
- **THEN** the client SHALL return a Go error wrapping the underlying network error
|
||||
|
||||
### Requirement: Authentication from environment
|
||||
The system SHALL read `PLANKA_URL` from the environment to determine the API base URL. The system SHALL read `PLANKA_API_KEY` from the environment to determine the API key. Global flags `--url` and `--api-key` SHALL override the corresponding environment variables. Flag values SHALL take precedence over environment variables.
|
||||
|
||||
#### Scenario: Auth from environment variables
|
||||
- **WHEN** `PLANKA_URL` and `PLANKA_API_KEY` are set in the environment
|
||||
- **AND** no `--url` or `--api-key` flags are provided
|
||||
- **THEN** the client SHALL use the environment variable values
|
||||
|
||||
#### Scenario: Flag overrides environment
|
||||
- **WHEN** `--url` or `--api-key` flags are provided
|
||||
- **THEN** the flag values SHALL take precedence over environment variables
|
||||
|
||||
#### Scenario: Missing configuration
|
||||
- **WHEN** neither the environment variable nor the flag is set for URL or API key
|
||||
- **THEN** the system SHALL print an error message and exit with code 1
|
||||
+22
@@ -0,0 +1,22 @@
|
||||
## MODIFIED Requirements
|
||||
|
||||
### Requirement: Root command and global flags
|
||||
The system SHALL provide a root command `pcli` that serves as the entry point. The root command SHALL register global flags: `--format` (string, default `json`, values `json` or `table`), `--url` (string, overrides `PLANKA_URL`), `--api-key` (string, overrides `PLANKA_API_KEY`), and `--log-level` (string, default `warn`, values `debug`, `info`, `warn`, `error`). The root command SHALL initialize the logger based on `--log-level` and configure it to write structured JSON to stderr. The root command SHALL validate that URL and API key are available (from flags or environment) before executing any subcommand.
|
||||
|
||||
#### Scenario: Display help
|
||||
- **WHEN** `pcli` is run with no arguments or `--help`
|
||||
- **THEN** the system SHALL display usage information listing all resource subcommands and global flags
|
||||
|
||||
#### Scenario: Invalid format flag
|
||||
- **WHEN** `--format` is set to an unsupported value
|
||||
- **THEN** the system SHALL print an error and exit with code 1
|
||||
|
||||
#### Scenario: Log level controls output
|
||||
- **WHEN** `--log-level=debug` is set
|
||||
- **THEN** DEBUG-level log entries SHALL appear on stderr
|
||||
- **AND** stdout SHALL contain only the command's data output
|
||||
|
||||
#### Scenario: Missing API key
|
||||
- **WHEN** neither `PLANKA_API_KEY` environment variable nor `--api-key` flag is provided
|
||||
- **THEN** the system SHALL print an error indicating `PLANKA_API_KEY` must be set via `--api-key` flag or `PLANKA_API_KEY` environment variable
|
||||
- **AND** the system SHALL exit with code 1
|
||||
@@ -0,0 +1,20 @@
|
||||
## 1. Client Authentication
|
||||
|
||||
- [x] 1.1 Rename `Token` and `HttpOnlyToken` fields to single `APIKey` field in `Client` struct in `client/client.go`
|
||||
- [x] 1.2 Update `NewClient` constructor to accept `(baseURL, apiKey string, logger *slog.Logger)` — remove `httpOnlyToken` parameter
|
||||
- [x] 1.3 Replace `Authorization: Bearer` header with `x-api-key` header in `Do()` method
|
||||
- [x] 1.4 Remove OIDC cookie logic (`httpOnlyToken` cookie attachment) from `Do()` method
|
||||
|
||||
## 2. CLI Flags and Environment Variables
|
||||
|
||||
- [x] 2.1 Rename `flagToken` to `flagAPIKey` and `flagHttpToken` removal in `cmd/root.go`
|
||||
- [x] 2.2 Replace `--token` flag with `--api-key` flag and remove `--http-token` flag in `cmd/root.go`
|
||||
- [x] 2.3 Replace `PLANKA_TOKEN` env var lookup with `PLANKA_API_KEY` in `PersistentPreRunE`
|
||||
- [x] 2.4 Remove `PLANKA_HTTP_TOKEN` env var lookup from `PersistentPreRunE`
|
||||
- [x] 2.5 Update error message to reference `PLANKA_API_KEY` and `--api-key`
|
||||
- [x] 2.6 Update `NewClient` call site in `PersistentPreRunE` to match new constructor signature
|
||||
- [x] 2.7 Remove OIDC-related debug log line (`oidc_mode` slog field)
|
||||
|
||||
## 3. Documentation
|
||||
|
||||
- [x] 3.1 Update `README.md` authentication section to reference `PLANKA_API_KEY` and `--api-key`
|
||||
Reference in New Issue
Block a user