Harbor is the server-local dynamic app platform for app.peisongxiao.com.

Current v1 scope:

  • Go runtime
  • docked-app landing page at /
  • app reverse proxying by slug
  • shared theme CSS derived from Lighthouse tokens, served by Harbor at /_harbor/static/theme.css
  • embedded local OIDC flow for e2e testing
  • Postgres-backed mutable platform state for users, direct permissions, theme/timezone preferences, and maintenance state
  • centralized guest vs authenticated permission injection
  • principal resolution by:
    • Harbor API key bearer token
    • Harbor session cookie
    • guest fallback
  • downstream identity headers for docked apps:
    • X-Harbor-User-Id
    • X-Harbor-Subject
    • X-Harbor-Username
    • X-Harbor-Display-Username
    • X-Harbor-Guest
    • X-Harbor-Roles
    • X-Harbor-Permissions
    • X-Harbor-Timezone
    • X-Harbor-Theme
    • X-Harbor-Auth-Method
    • X-Harbor-API-Key-Id when the request is authenticated by API key
  • management socket contract for app lifecycle
  • global maintenance mode with drain/resume signaling
  • built-in authenticated account surface at /myself/
  • built-in account APIs under /_harbor/api/me*
  • DB-backed Harbor API keys
  • docked app source resolution from exactly one of:
    • SOURCE_DIR
    • CLONE_URL + BRANCH

Harbor is operated through lighthouse-cli:

  • lighthouse validate --target harbor
  • lighthouse build --target harbor
  • lighthouse apply --target harbor
  • lighthouse clean --target harbor
  • lighthouse harbor local
  • lighthouse harbor status
  • lighthouse harbor add-user
  • lighthouse harbor set-password
  • lighthouse harbor list-permissions
  • lighthouse harbor list-all-permissions
  • lighthouse harbor add-permissions
  • lighthouse harbor delete-permissions
  • lighthouse harbor delete-user
  • lighthouse harbor migrate-db
  • lighthouse harbor maintenance on|off

User storage model:

  • HARBOR.OIDC.EMBEDDED_USERS are bootstrap-only seed users
  • mutable Harbor users and platform state live in Harbor’s Postgres schema
  • after lighthouse harbor migrate-db, Harbor reads steady-state auth, preferences, and maintenance state from Postgres
  • once the Harbor database is initialized, it is safe to remove EMBEDDED_USERS from Harbor config
  • Harbor reloads DB-backed user and platform state while serving requests, so permission and preference changes take effect without a restart
  • canonical usernames are normalized to lowercase and restricted to a-z, 0-9, _, and -
  • display usernames stay separate and human-facing
  • the admin permission is a wildcard and satisfies all app permission checks

Built-in account surface:

  • /myself/ is a Harbor-owned page, not a docked app
  • it is only shown to authenticated browser sessions
  • guests do not see the Myself entry
  • account APIs are same-origin and session-auth only for mutation:
    • GET /_harbor/api/me
    • GET /_harbor/api/me/permissions
    • GET /_harbor/api/me/api-keys
    • PATCH /_harbor/api/me/preferences
    • PATCH /_harbor/api/me/profile
    • POST /_harbor/api/me/password
    • POST /_harbor/api/me/api-keys
    • DELETE /_harbor/api/me/api-keys/:id

Harbor API keys:

  • stored in Harbor’s Postgres schema
  • token format:
    • hpk_1_<public_id>_<secret>
  • Harbor stores only the hashed secret
  • keys are bound to the Harbor user, not to a username slug
  • API keys participate in principal resolution and can authenticate docked app requests or Harbor admin routes when the user has the required permissions

Proxy authorization notes:

  • GUEST_CAN_VIEW=false blocks unauthenticated guests at the Harbor proxy edge
  • when an app declares READ_PERMISSIONS, authenticated users must satisfy at least one of them unless they have admin
  • WRITE_PERMISSIONS remain metadata in Harbor v1; app-local write enforcement still lives inside the docked app
  • app slug myself is reserved for Harbor’s built-in account surface

The runtime binary itself is built from this directory.

Current production direction:

  • Harbor itself is deployed from this repo
  • harbor-schedule is the first production-facing docked app
  • harbor-todo remains an e2e/testing app rather than a production app