Skip to content

API: Allow webhook management with platform API keys (skip Cognito for automation) #376

Description

@krokoko

Component

API or orchestration

Describe the feature

Add platform API keys as a first-class authentication mechanism so operators and automation can manage webhooks (and optionally other REST endpoints) without Cognito user accounts.

Today the split is:

  • CLI / REST API (POST /v1/webhooks, GET /v1/webhooks, task CRUD, etc.) — requires a Cognito JWT (bgagent login or manual initiate-auth).
  • Webhook task submission (POST /v1/webhooks/tasks) — already uses HMAC-SHA256 with per-webhook secrets; no Cognito on the wire.

The gap: creating and managing webhook integrations still requires Cognito. CI pipelines, internal tools, and workshop participants who only want "fire a task from GitHub Actions" must first stand up Cognito users, configure the CLI, and obtain JWTs — even though webhook invocation was designed to be Cognito-free.

Use case

  • CI/CD and GitHub Actions want to provision a webhook (bgagent webhook create or REST equivalent) from a pipeline without storing Cognito username/password or refreshing JWTs.
  • Workshop / eval scenarios where participants should submit tasks via webhooks quickly, without the full Cognito onboarding path documented in Quick Start Steps 5–6.
  • Service-to-service integrations (internal task routers, bots) that prefer long-lived API keys over interactive Cognito login and token refresh.
  • Operators who already use webhook HMAC for task creation but hit friction when the setup step still depends on human Cognito credentials.

I'm always frustrated when I have to create a Cognito user and run bgagent login just to mint a webhook secret for a headless integration.

Proposed solution

Phase 1 — API keys for webhook management

  1. Introduce a PlatformApiKey (or similar) resource stored in DynamoDB with:
    • key_id, hashed secret, user_id (owner / task attribution), scopes (e.g. webhooks:manage, webhooks:invoke, tasks:read), status, created_at, expires_at (optional).
  2. New authorizer path on API Gateway (or extend existing) accepting Authorization: ApiKey <key> or X-API-Key header alongside the existing Cognito authorizer.
  3. Scope POST/GET/DELETE /v1/webhooks* to accept either Cognito JWT or an API key with webhooks:manage.
  4. CLI: bgagent api-key create|list|revoke (admin or self-service, TBD) — no login required when using --api-key flag or env BGAGENT_API_KEY.
  5. Document the headless flow: deploy → create API key (one-time admin bootstrap or bgagent admin create-api-key) → bgagent webhook create --api-key … → use returned HMAC secret in CI.

Phase 2 (optional) — broader API key access

  • Extend scoped keys to read-only task APIs (tasks:read, tasks:cancel) for ops tooling.
  • Explicitly out of scope for v1: replacing Cognito for human CLI sessions (keep bgagent login as default for interactive use).

Security notes

  • Store only hashed secrets (same pattern as webhook secrets in Secrets Manager).
  • Keys inherit user_id for task ownership (mirrors webhook owner model in webhook-authorizer.ts).
  • Rate-limit and audit API key usage (CloudWatch metric dimension on key_id).
  • See IDENTITY_AND_AUTH.md and SECURITY.md for alignment.

Other information

  • Related: #17 (post-deploy setup UX — API keys reduce Cognito steps for automation).
  • Current webhook auth docs: Webhook integration, cdk/src/handlers/webhook-authorizer.ts, cdk/src/constructs/task-api.ts (Cognito-gated POST /webhooks).
  • Linear/Slack/Jira setup wizards today assume Cognito for the operator CLI session; API keys would not replace those OAuth flows.

Acknowledgements

  • I may be able to implement this feature
  • This might be a breaking change

Metadata

Metadata

Labels

P0highest priorityclibgagent CLI commands and HTTP clientenhancementNew feature or requestorchestrationTask lifecycle, REST API handlers, orchestrator Lambdas, durable executionsecurityCedar/HITL, IAM least-privilege, secrets, PII/DLP, guardrails, supply-chain/CVE

Type

No type

Fields

No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions