Documentation

Source-of-truth docs, references, plans, and product material across Harbor surfaces.

Commercial And Brand

Agent Token Security Plan

Add **Node-local agent tokens** so Harbor Node can require a real credential for network action calls and attach those calls to a stable per-agent identity.

commercial and brandagenttokensecurityplan
Source: AGENT_TOKEN_SECURITY_PLAN.md

Agent Token Security Plan

Summary

Add Node-local agent tokens so Harbor Node can require a real credential for network action calls and attach those calls to a stable per-agent identity.

This should unlock:

  • per-agent or per-integration credentials
  • per-agent permissions
  • cleaner audit attribution
  • better approval attribution
  • token revocation and deletion
  • future per-agent rate limits and policy overlays

This plan is intentionally Node-local first. It should not depend on Cloud, Fleet, billing, or the public website.

Why This Matters

Today Harbor Node accepts action execution requests on the local API without a first-class Node-issued bearer credential model.

Relevant current wiring:

  • live action execution happens at apps/harbor-node-api/src/index.ts on POST /v1/actions/:actionId/execute
  • the current route trusts requestedBy from the request body and writes that into audit and approval records
  • approvals and audit already exist and are good places to attach a stronger caller identity
  • Harbor UI already shows audit and approval behavior, so this feature can integrate into an existing operator surface instead of inventing one from scratch

This means we can add a real auth layer without replacing Harbor Guard, Harbor audit, or the action model.

Security Position

Do not use an 8 to 10 character bearer token for real network auth.

Recommended structure:

  • agentId: short, human-friendly identifier for UI and logs
  • token name: human-friendly label such as Claude Desktop, OpenCode Agent, or Nightly Gmail Worker
  • secret token: random opaque bearer token, one-time reveal only

Recommended secret length:

  • minimum: 16 random characters
  • preferred MVP: 20 to 24 random characters

Recommended storage:

  • store only a token hash
  • optionally store a short fingerprint for UI display
  • never log the raw token
  • never return the raw token after creation

Scope

In Scope For Pass 1

  • Node-local token storage in SQLite
  • create / list / revoke / delete token management
  • one-time secret reveal UI
  • token hashing and verification
  • permission scopes on the token
  • protect remote action execution with bearer token auth
  • use resolved token identity in audit and approval records
  • basic last-used tracking

Explicitly Out Of Scope For Pass 1

  • Cloud sync of tokens
  • website account token management
  • Fleet-wide token replication
  • org / team management
  • token expiry policies
  • IP allowlists
  • OAuth for agents
  • signed request schemes
  • mTLS
  • broad auth across every Harbor route

Current Wiring Notes

Execution route

Current execution is handled in apps/harbor-node-api/src/index.ts.

Current behavior:

- local audit events - approval records - optional cloud activity sync metadata

  • route: POST /v1/actions/:actionId/execute
  • request body includes requestedBy
  • route writes requestedBy into:

Existing attribution model

Shared caller and audit shapes already exist in packages/shared/src/index.ts.

This is useful because we do not need to invent a whole new audit model. We can resolve the token into a stable HarborActor and feed that into the existing system.

SDK

The SDK in packages/sdk-ts/src/index.ts already centralizes requests and can be extended later with optional bearer token support for headless agents.

Proposed Model

Agent profile

Add an optional agent profile concept.

Purpose:

  • group one or more tokens under one logical agent identity
  • allow better audit naming
  • allow future per-agent policy and limits

Fields:

  • agentId
  • name
  • description?
  • status
  • createdAt
  • updatedAt

Recommended MVP:

  • start with agent profiles present in the model
  • token creation requires linking to one profile
  • allow one token per agent as the normal path

Agent token

Fields:

  • tokenId
  • agentId
  • name
  • permissions
  • tokenHash
  • tokenFingerprint
  • createdAt
  • lastUsedAt?
  • revokedAt?
  • status

Token secret format:

  • opaque random bearer string
  • optional prefix for recognition such as hn_

Example:

  • hn_A7f2mPq91Lx4Vr8K

Permission model

Start route-based, not hyper-granular.

Recommended MVP permissions:

  • actions.execute
  • actions.read
  • ports.read
  • approvals.read
  • approvals.resolve
  • audit.read
  • settings.read

Do not start with dozens of fine-grained per-action scopes.

If later needed, add:

  • per-port scopes
  • per-category scopes
  • read-only versus execute-only subsets

Data Model

Add SQLite tables in apps/harbor-node-api/src/store.ts.

agent_profiles

Columns:

  • agent_id TEXT PRIMARY KEY
  • name TEXT NOT NULL
  • description TEXT
  • status TEXT NOT NULL
  • created_at TEXT NOT NULL
  • updated_at TEXT NOT NULL

agent_tokens

Columns:

  • token_id TEXT PRIMARY KEY
  • agent_id TEXT NOT NULL
  • name TEXT NOT NULL
  • permissions_json TEXT NOT NULL
  • token_hash TEXT NOT NULL
  • token_fingerprint TEXT NOT NULL
  • status TEXT NOT NULL
  • last_used_at TEXT
  • revoked_at TEXT
  • created_at TEXT NOT NULL
  • updated_at TEXT NOT NULL

Indexes:

  • idx_agent_tokens_agent_id
  • idx_agent_tokens_status

Foreign key:

  • agent_id -> agent_profiles.agent_id

API Design

Add shared contracts in packages/shared/src/index.ts.

Management routes

  • GET /v1/agent-profiles
  • POST /v1/agent-profiles
  • GET /v1/agent-tokens
  • POST /v1/agent-tokens
  • POST /v1/agent-tokens/:tokenId/revoke
  • DELETE /v1/agent-tokens/:tokenId

Creation response:

  • return token metadata
  • return plaintext token once

List response:

- name - linked agent - permissions - created - last used - status - fingerprint

  • no plaintext token
  • show:

Authenticated execution routes

Pass 1 should require bearer token auth for:

  • POST /v1/actions/:actionId/execute

Pass 1 can optionally protect more read routes later, but action execution is the important first boundary.

Bearer format:

  • Authorization: Bearer <token>

Behavior:

  • missing token -> 401
  • invalid token -> 401
  • revoked token -> 403
  • missing permission -> 403

Execution Flow

Token creation

  1. Operator opens Token Manager in Harbor UI.
  2. Operator creates or selects an agent profile.
  3. Operator chooses token name and permissions.
  4. Harbor generates a secret token.
  5. Harbor stores only the hash and metadata.
  6. Harbor shows the secret once in a modal.
  7. Operator copies it into the target agent environment.
  8. After modal close, the secret is gone.

Action execution

  1. Agent sends bearer token in Authorization header.
  2. Harbor verifies token hash.
  3. Harbor resolves token to agent profile and permissions.
  4. Harbor maps that into requestedBy.
  5. Harbor checks token permission.
  6. Harbor runs existing Harbor Guard policy.
  7. Harbor writes audit / approval / cloud activity using the resolved token identity.

UI Plan

Add a new Harbor UI page or section called Security.

Recommended layout:

  • Agent Profiles
  • Agent Tokens
  • Create Token
  • Revoked Tokens

Agent profile card

  • name
  • description
  • token count
  • last used token time

Token list row/card

  • token name
  • linked agent
  • permission pills
  • fingerprint
  • created at
  • last used at
  • status
  • revoke button
  • delete button

Create token modal

Fields:

  • profile or agent selection
  • token name
  • permission checklist

After creation:

  • one-time token reveal
  • copy button
  • confirm close

UX guardrails

  • do not show the full token after creation
  • make revoke obvious and low risk
  • make delete destructive only after revoke or confirmation
  • explain that one token per agent is the recommended default

Shared Contract Additions

Add types for:

  • HarborAgentProfile
  • HarborAgentTokenSummary
  • HarborAgentTokenCreateRequest
  • HarborAgentTokenCreateResponse
  • HarborAgentTokenListResponse
  • HarborAgentTokenRevokeResponse
  • HarborAgentProfileCreateRequest
  • HarborAgentProfileListResponse

SDK Additions

Extend packages/sdk-ts/src/index.ts.

Recommended additions:

- list profiles - create profile - list tokens - create token - revoke token - delete token

  • optional bearerToken in client options
  • request helper adds Authorization: Bearer ...
  • management helpers for:

Do not make bearer token mandatory for Harbor UI’s current operator calls unless that becomes a separate milestone.

Audit And Approval Integration

Resolved token identity should be written into the existing audit system.

Recommended actor mapping:

  • kind: "agent"
  • name: <agent profile name>

Add detail metadata:

  • agentId
  • tokenId
  • tokenName
  • tokenFingerprint

Important:

  • audit should not store raw bearer token
  • cloud activity sync should keep only safe derived identity fields

Pass Breakdown

Pass 1A: Storage and shared contracts

  • add shared types
  • add SQLite tables and migrations
  • add hash / verify helpers
  • add store methods

Pass 1B: Node API management routes

  • list/create/revoke/delete token routes
  • profile list/create routes
  • one-time secret creation response

Pass 1C: Execution auth

  • require bearer token on POST /v1/actions/:actionId/execute
  • permission checks
  • audit attribution through resolved token identity

Pass 1D: Harbor UI

  • add Security page
  • token list
  • create token modal
  • revoke/delete actions
  • one-time reveal modal

Pass 1E: SDK support

  • optional bearer token support
  • management helpers

Guardrails

  • do not trust requestedBy from body when a bearer token is present
  • do not log raw tokens
  • do not store raw tokens
  • do not introduce Cloud dependency
  • do not bypass Harbor Guard approvals
  • do not protect every route in Pass 1
  • do not overcomplicate scopes before the base model works

Open Decisions

Agent profile required?

Recommendation:

  • yes, but lightweight

Reason:

  • lets us cleanly support “one token per agent” while still allowing rotation later

Token length

Recommendation:

  • 20 to 24 random characters

Reason:

  • short enough to copy
  • long enough for real auth

Execution-only or broader API auth?

Recommendation:

  • start with execution-only

Reason:

  • it secures the highest-risk route first
  • avoids blocking operator UI work before the model is mature

Test Plan

Storage and API

  • create profile succeeds
  • create token succeeds
  • plaintext token appears only in create response
  • list tokens never returns plaintext
  • revoked token cannot execute
  • deleted token disappears from list
  • invalid token returns 401
  • token missing required permission returns 403

Execution and audit

  • valid token can execute allowed action
  • audit event shows agent identity
  • approval request shows agent identity
  • cloud activity sync uses safe caller metadata

UI

  • token create modal shows one-time reveal
  • copy button works
  • revoke changes status immediately
  • delete removes token from list
  • permissions render clearly

Implement Pass 1A through Pass 1C first.

That gives Harbor:

  • real token storage
  • real execution auth
  • real audit attribution

Then add the Harbor UI management surface as the next vertical slice.