Documentation
¶
Index ¶
- func NewRouter(cfg RouterConfig) http.Handler
- func RealIP(cfg *RealIPConfig) func(http.Handler) http.Handler
- func SubdomainProxy(agentDomain string, database *db.DB, s3 *storage.S3Client, ...) http.Handler
- type AuthHandler
- func (h *AuthHandler) Activate(w http.ResponseWriter, r *http.Request)
- func (h *AuthHandler) ChangePassword(w http.ResponseWriter, r *http.Request)
- func (h *AuthHandler) ListSessions(w http.ResponseWriter, r *http.Request)
- func (h *AuthHandler) Login(w http.ResponseWriter, r *http.Request)
- func (h *AuthHandler) Logout(w http.ResponseWriter, r *http.Request)
- func (h *AuthHandler) Me(w http.ResponseWriter, r *http.Request)
- func (h *AuthHandler) Refresh(w http.ResponseWriter, r *http.Request)
- func (h *AuthHandler) RevokeSession(w http.ResponseWriter, r *http.Request)
- func (h *AuthHandler) Status(w http.ResponseWriter, r *http.Request)
- type GitCredentialsHandler
- type GitWebhookHandler
- type GrantsHandler
- func (h *GrantsHandler) GrantModel(w http.ResponseWriter, r *http.Request)
- func (h *GrantsHandler) ListModelGrants(w http.ResponseWriter, r *http.Request)
- func (h *GrantsHandler) ModelUsage(w http.ResponseWriter, r *http.Request)
- func (h *GrantsHandler) RevokeModelGrant(w http.ResponseWriter, r *http.Request)
- type InboundOAuthGC
- type NeedsHandler
- func (h *NeedsHandler) BindNeed(w http.ResponseWriter, r *http.Request)
- func (h *NeedsHandler) CreateForNeed(w http.ResponseWriter, r *http.Request)
- func (h *NeedsHandler) ListCandidates(w http.ResponseWriter, r *http.Request)
- func (h *NeedsHandler) ListNeeds(w http.ResponseWriter, r *http.Request)
- func (h *NeedsHandler) UnbindNeed(w http.ResponseWriter, r *http.Request)
- type PasskeyHandler
- func (h *PasskeyHandler) Delete(w http.ResponseWriter, r *http.Request)
- func (h *PasskeyHandler) List(w http.ResponseWriter, r *http.Request)
- func (h *PasskeyHandler) LoginBegin(w http.ResponseWriter, r *http.Request)
- func (h *PasskeyHandler) LoginFinish(w http.ResponseWriter, r *http.Request)
- func (h *PasskeyHandler) RegisterBegin(w http.ResponseWriter, r *http.Request)
- func (h *PasskeyHandler) RegisterFinish(w http.ResponseWriter, r *http.Request)
- func (h *PasskeyHandler) RemovePassword(w http.ResponseWriter, r *http.Request)
- func (h *PasskeyHandler) Rename(w http.ResponseWriter, r *http.Request)
- func (h *PasskeyHandler) SetPassword(w http.ResponseWriter, r *http.Request)
- type ProvidersHandler
- type RealIPConfig
- type ResourcesHandler
- func (h *ResourcesHandler) Consumers(w http.ResponseWriter, r *http.Request)
- func (h *ResourcesHandler) Delete(w http.ResponseWriter, r *http.Request)
- func (h *ResourcesHandler) List(w http.ResponseWriter, r *http.Request)
- func (h *ResourcesHandler) Rename(w http.ResponseWriter, r *http.Request)
- func (h *ResourcesHandler) Revoke(w http.ResponseWriter, r *http.Request)
- type RouterConfig
- type UsageHandler
- type UsersHandler
- func (h *UsersHandler) Create(w http.ResponseWriter, r *http.Request)
- func (h *UsersHandler) Delete(w http.ResponseWriter, r *http.Request)
- func (h *UsersHandler) List(w http.ResponseWriter, r *http.Request)
- func (h *UsersHandler) ListSelectable(w http.ResponseWriter, r *http.Request)
- func (h *UsersHandler) UpdateMe(w http.ResponseWriter, r *http.Request)
- func (h *UsersHandler) UpdateRole(w http.ResponseWriter, r *http.Request)
- type WSHandler
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func NewRouter ¶
func NewRouter(cfg RouterConfig) http.Handler
func RealIP ¶
func RealIP(cfg *RealIPConfig) func(http.Handler) http.Handler
RealIP returns middleware that canonicalizes r.RemoteAddr to an IP and, when the direct peer is trusted, replaces it with the forwarded client IP. Forwarding headers are removed before downstream handlers run so r.RemoteAddr remains the only client-IP source inside the application.
func SubdomainProxy ¶
func SubdomainProxy(agentDomain string, database *db.DB, s3 *storage.S3Client, files *agentstoragesvc.Service, dispatcher *trigger.Dispatcher, bridgeMgr *trigger.BridgeManager, jwtSecret, publicURL string, inner http.Handler) http.Handler
SubdomainProxy wraps the main router and intercepts requests whose Host header matches {slug}.{agentDomain}. Matching requests are authenticated according to the route's access level and reverse-proxied to the agent's container. Non-matching requests fall through to inner.
bridgeMgr is required for the Telegram Web App auto-auth flow: the /__air/tg/auth intercept verifies initData against the bridge's bot token, which bridgeMgr decrypts on demand.
Types ¶
type AuthHandler ¶
type AuthHandler struct {
// contains filtered or unexported fields
}
func NewAuthHandler ¶
func (*AuthHandler) Activate ¶
func (h *AuthHandler) Activate(w http.ResponseWriter, r *http.Request)
Activate performs one-time setup: creates the tenant and first admin user. Returns 409 if a tenant already exists.
func (*AuthHandler) ChangePassword ¶
func (h *AuthHandler) ChangePassword(w http.ResponseWriter, r *http.Request)
ChangePassword updates the current user's password and clears the must_change_password flag.
func (*AuthHandler) ListSessions ¶ added in v0.4.0
func (h *AuthHandler) ListSessions(w http.ResponseWriter, r *http.Request)
func (*AuthHandler) Login ¶
func (h *AuthHandler) Login(w http.ResponseWriter, r *http.Request)
func (*AuthHandler) Logout ¶ added in v0.4.0
func (h *AuthHandler) Logout(w http.ResponseWriter, r *http.Request)
func (*AuthHandler) Me ¶
func (h *AuthHandler) Me(w http.ResponseWriter, r *http.Request)
func (*AuthHandler) Refresh ¶
func (h *AuthHandler) Refresh(w http.ResponseWriter, r *http.Request)
func (*AuthHandler) RevokeSession ¶ added in v0.4.0
func (h *AuthHandler) RevokeSession(w http.ResponseWriter, r *http.Request)
func (*AuthHandler) Status ¶
func (h *AuthHandler) Status(w http.ResponseWriter, r *http.Request)
Status returns whether the system has been activated (tenant exists). The activation code itself is generated on airlock startup (see ensureActivationCode in cmd/airlock/main.go) — this handler only reports state, never mutates it.
type GitCredentialsHandler ¶ added in v0.4.0
type GitCredentialsHandler struct {
// contains filtered or unexported fields
}
GitCredentialsHandler owns the per-user PAT credential surface at /api/v1/me/git/credentials. Thin wrapper over service/gitcredentials: parse + auth principal here; gating, encryption, and DB inside the service.
func NewGitCredentialsHandler ¶ added in v0.4.0
func NewGitCredentialsHandler(svc *gitcredssvc.Service) *GitCredentialsHandler
func (*GitCredentialsHandler) Create ¶ added in v0.4.0
func (h *GitCredentialsHandler) Create(w http.ResponseWriter, r *http.Request)
func (*GitCredentialsHandler) Delete ¶ added in v0.4.0
func (h *GitCredentialsHandler) Delete(w http.ResponseWriter, r *http.Request)
func (*GitCredentialsHandler) List ¶ added in v0.4.0
func (h *GitCredentialsHandler) List(w http.ResponseWriter, r *http.Request)
type GitWebhookHandler ¶ added in v0.4.0
type GitWebhookHandler struct {
// contains filtered or unexported fields
}
GitWebhookHandler accepts push notifications from external git providers (GitHub, GitLab) at /webhooks/git/{agentID}. No JWT — per the public-webhook-ingress pattern; signature verification gates it.
On a valid push to the agent's configured branch: pulls the new HEAD into the local repo, then enqueues an upgrade with empty instruction (the existing bare-rebuild path: build image at new HEAD, validate migrations, swap container).
func NewGitWebhookHandler ¶ added in v0.4.0
func NewGitWebhookHandler(database *db.DB, b *builder.BuildService, secretStore secrets.Store, logger *zap.Logger) *GitWebhookHandler
func (*GitWebhookHandler) Handle ¶ added in v0.4.0
func (h *GitWebhookHandler) Handle(w http.ResponseWriter, r *http.Request)
Handle accepts an external git provider's push notification. The wire shape — request bodies, response error envelopes, signature headers — is dictated by GitHub / GitLab, so this endpoint stays on raw JSON (no Principal, no proto): airlockvet:allow-writejson and allow-dbq reasons below point at this contract.
type GrantsHandler ¶ added in v0.4.0
type GrantsHandler struct {
// contains filtered or unexported fields
}
GrantsHandler serves model entitlement management.
func NewGrantsHandler ¶ added in v0.4.0
func NewGrantsHandler(svc *grantssvc.Service) *GrantsHandler
func (*GrantsHandler) GrantModel ¶ added in v0.4.0
func (h *GrantsHandler) GrantModel(w http.ResponseWriter, r *http.Request)
GrantModel handles POST /api/v1/model-grants.
func (*GrantsHandler) ListModelGrants ¶ added in v0.4.0
func (h *GrantsHandler) ListModelGrants(w http.ResponseWriter, r *http.Request)
ListModelGrants handles GET /api/v1/model-grants.
func (*GrantsHandler) ModelUsage ¶ added in v0.4.0
func (h *GrantsHandler) ModelUsage(w http.ResponseWriter, r *http.Request)
ModelUsage handles GET /api/v1/model-grants/usage?providerId=&model= — how a (provider, model) is configured, so the UI can confirm a disable.
func (*GrantsHandler) RevokeModelGrant ¶ added in v0.4.0
func (h *GrantsHandler) RevokeModelGrant(w http.ResponseWriter, r *http.Request)
RevokeModelGrant handles DELETE /api/v1/model-grants/{id}.
type InboundOAuthGC ¶ added in v0.4.0
type InboundOAuthGC struct {
// contains filtered or unexported fields
}
InboundOAuthGC sweeps expired authorization codes and consent transactions, expired/long-consumed refresh tokens, ancient grants, inactive OAuth clients, expired WebAuthn ceremonies, device-login handoffs, first-party sessions, and DCR rate-limit buckets. Mirrors oauth.RefreshJob in cadence — 5min ticker, started from cmd/airlock/serve.go and stopped via ctx cancellation.
The query files document the retention rules:
- authz codes: hard delete past expires_at (60s TTL).
- consent transactions: hard delete past expires_at (10min TTL).
- refresh tokens: past expires_at OR consumed >7d ago.
- grants: revoked-or-expired more than 1y ago.
- clients: never used after 24h or inactive for 180d, when unreferenced by active authorization state or retained refresh material.
Each tick is idempotent and safe to call from multiple replicas (the DELETE is row-level; concurrent deletes harmlessly target disjoint rows because the GC window slides).
func NewInboundOAuthGC ¶ added in v0.4.0
func NewInboundOAuthGC(database *db.DB, logger *zap.Logger) *InboundOAuthGC
func (*InboundOAuthGC) Run ¶ added in v0.4.0
func (j *InboundOAuthGC) Run(ctx context.Context)
Run blocks until ctx is cancelled, sweeping every 5 minutes.
type NeedsHandler ¶ added in v0.4.0
type NeedsHandler struct {
// contains filtered or unexported fields
}
NeedsHandler serves the agent resource-need surface: list needs, list shape-compatible candidate resources for a need, bind an existing resource, or create a new one from the need's spec.
func NewNeedsHandler ¶ added in v0.4.0
func NewNeedsHandler(svc *needssvc.Service) *NeedsHandler
func (*NeedsHandler) BindNeed ¶ added in v0.4.0
func (h *NeedsHandler) BindNeed(w http.ResponseWriter, r *http.Request)
BindNeed handles POST /api/v1/agents/{agentID}/needs/{type}/{slug}/bind.
func (*NeedsHandler) CreateForNeed ¶ added in v0.4.0
func (h *NeedsHandler) CreateForNeed(w http.ResponseWriter, r *http.Request)
CreateForNeed handles POST /api/v1/agents/{agentID}/needs/{type}/{slug}/create.
func (*NeedsHandler) ListCandidates ¶ added in v0.4.0
func (h *NeedsHandler) ListCandidates(w http.ResponseWriter, r *http.Request)
ListCandidates handles GET /api/v1/agents/{agentID}/needs/{type}/{slug}/candidates.
func (*NeedsHandler) ListNeeds ¶ added in v0.4.0
func (h *NeedsHandler) ListNeeds(w http.ResponseWriter, r *http.Request)
ListNeeds handles GET /api/v1/agents/{agentID}/needs.
func (*NeedsHandler) UnbindNeed ¶ added in v0.4.0
func (h *NeedsHandler) UnbindNeed(w http.ResponseWriter, r *http.Request)
UnbindNeed handles DELETE /api/v1/agents/{agentID}/needs/{type}/{slug}/bind.
type PasskeyHandler ¶ added in v0.4.0
type PasskeyHandler struct {
// contains filtered or unexported fields
}
PasskeyHandler owns the WebAuthn surface: the public login ceremony at /auth/passkey/* and the authenticated self-service at /api/v1/me/passkeys/* and /api/v1/me/password. Ceremony begin/finish exchange raw WebAuthn JSON (browser-produced attestation/assertion that go-webauthn parses directly); the management responses are proto.
func NewPasskeyHandler ¶ added in v0.4.0
func NewPasskeyHandler(svc *passkeyssvc.Service, database *db.DB, jwtSecret, publicURL string) *PasskeyHandler
func (*PasskeyHandler) Delete ¶ added in v0.4.0
func (h *PasskeyHandler) Delete(w http.ResponseWriter, r *http.Request)
func (*PasskeyHandler) List ¶ added in v0.4.0
func (h *PasskeyHandler) List(w http.ResponseWriter, r *http.Request)
func (*PasskeyHandler) LoginBegin ¶ added in v0.4.0
func (h *PasskeyHandler) LoginBegin(w http.ResponseWriter, r *http.Request)
func (*PasskeyHandler) LoginFinish ¶ added in v0.4.0
func (h *PasskeyHandler) LoginFinish(w http.ResponseWriter, r *http.Request)
func (*PasskeyHandler) RegisterBegin ¶ added in v0.4.0
func (h *PasskeyHandler) RegisterBegin(w http.ResponseWriter, r *http.Request)
func (*PasskeyHandler) RegisterFinish ¶ added in v0.4.0
func (h *PasskeyHandler) RegisterFinish(w http.ResponseWriter, r *http.Request)
func (*PasskeyHandler) RemovePassword ¶ added in v0.4.0
func (h *PasskeyHandler) RemovePassword(w http.ResponseWriter, r *http.Request)
func (*PasskeyHandler) Rename ¶ added in v0.4.0
func (h *PasskeyHandler) Rename(w http.ResponseWriter, r *http.Request)
func (*PasskeyHandler) SetPassword ¶ added in v0.4.0
func (h *PasskeyHandler) SetPassword(w http.ResponseWriter, r *http.Request)
type ProvidersHandler ¶
type ProvidersHandler struct {
// contains filtered or unexported fields
}
func NewProvidersHandler ¶
func NewProvidersHandler(svc *providerssvc.Service) *ProvidersHandler
func (*ProvidersHandler) Create ¶
func (h *ProvidersHandler) Create(w http.ResponseWriter, r *http.Request)
func (*ProvidersHandler) Delete ¶
func (h *ProvidersHandler) Delete(w http.ResponseWriter, r *http.Request)
func (*ProvidersHandler) List ¶
func (h *ProvidersHandler) List(w http.ResponseWriter, r *http.Request)
func (*ProvidersHandler) Update ¶
func (h *ProvidersHandler) Update(w http.ResponseWriter, r *http.Request)
type RealIPConfig ¶
type RealIPConfig struct {
// TrustedPeers limits which immediate network peers may present authenticated
// forwarding headers. The shared secret remains required for every match.
TrustedPeers []*net.IPNet
// Limit selects the exact rightmost entry in X-Forwarded-For.
// Default: 1 (single proxy).
Limit int
// contains filtered or unexported fields
}
RealIPConfig configures the real IP extraction middleware.
func ParseRealIPConfig ¶
func ParseRealIPConfig(trustedPeers string, limit int, proxyAuthSecret string) *RealIPConfig
ParseRealIPConfig builds a RealIPConfig from the raw env values. trustedPeers is a comma-separated list of immediate-peer CIDRs. limit is the number of proxy hops (minimum 1).
func (*RealIPConfig) Enabled ¶
func (c *RealIPConfig) Enabled() bool
Enabled returns true if any proxy trust is configured.
type ResourcesHandler ¶ added in v0.4.0
type ResourcesHandler struct {
// contains filtered or unexported fields
}
ResourcesHandler serves the per-user available-resource inventory at /api/v1/resources. Thin wrapper over service/resources: parse + auth principal here; capability resolution and DB access live in the service.
func NewResourcesHandler ¶ added in v0.4.0
func NewResourcesHandler(svc *resourcessvc.Service) *ResourcesHandler
func (*ResourcesHandler) Consumers ¶ added in v0.4.0
func (h *ResourcesHandler) Consumers(w http.ResponseWriter, r *http.Request)
Consumers handles GET /api/v1/resources/{type}/{id}/consumers.
func (*ResourcesHandler) Delete ¶ added in v0.4.0
func (h *ResourcesHandler) Delete(w http.ResponseWriter, r *http.Request)
Delete handles DELETE /api/v1/resources/{type}/{id} — remove an owned resource.
func (*ResourcesHandler) List ¶ added in v0.4.0
func (h *ResourcesHandler) List(w http.ResponseWriter, r *http.Request)
List handles GET /api/v1/resources — the connections / MCP servers / exec endpoints available through ownership or grants, with caller capabilities.
func (*ResourcesHandler) Rename ¶ added in v0.4.0
func (h *ResourcesHandler) Rename(w http.ResponseWriter, r *http.Request)
Rename handles PATCH /api/v1/resources/{type}/{id}.
func (*ResourcesHandler) Revoke ¶ added in v0.4.0
func (h *ResourcesHandler) Revoke(w http.ResponseWriter, r *http.Request)
Revoke handles POST /api/v1/resources/{type}/{id}/revoke — clear an owned connection's / MCP server's stored credentials (affects every agent binding it).
type RouterConfig ¶
type RouterConfig struct {
DB *db.DB
JWTSecret string
// Real-time
Hub *realtime.Hub
PubSub *realtime.PubSub
Handler *realtime.Handler
// Secrets store. Today wraps a local AES-GCM encryptor; the interface
// is forward-compatible with a Vault-backed implementation.
Secrets secrets.Store
// S3 storage
S3Client *storage.S3Client
// Build service
BuildService *builder.BuildService
// Public URL (for OAuth callbacks, auth URLs)
PublicURL string
// OAuth client
OAuthClient *oauth.Client
// Telegram driver (for bridge validation via getMe)
TelegramDriver *trigger.TelegramDriver
// Trigger system
Dispatcher *trigger.Dispatcher
Scheduler *trigger.Scheduler
BridgeManager *trigger.BridgeManager
// Container manager
Containers container.ContainerManager
// Prompt proxy (for web conversations)
PromptProxy *trigger.PromptProxy
// Agent subdomain routing (e.g. "airlock.host" → {slug}.airlock.host)
AgentDomain string
// AgentBaseURL builds an agent's external route base
// ({scheme}://{slug}.{domain}[:port]). Sourced from config.Config —
// the single place that derives it; handlers never re-derive.
AgentBaseURL func(slug string) string
// LLM debugging proxy (e.g. telescope -watch)
LLMProxyURL string
// Dev escape hatch: force base64 attachment delivery regardless of
// provider URL capability. Useful when the public URL isn't reachable
// from the model provider (e.g. localhost without a tunnel).
ForceInlineAttachments bool
// Non-public CIDRs available to Airlock-brokered agent HTTP calls.
HTTPNetwork *networkpolicy.Policy
// Path to the on-disk activation code file — cleared after Activate
// succeeds so the one-time secret doesn't linger on disk.
ActivationCodeFile string
// Reverse proxy real IP extraction
RealIP *RealIPConfig
// Logger
Logger *zap.Logger
}
type UsageHandler ¶ added in v0.4.0
type UsageHandler struct {
// contains filtered or unexported fields
}
UsageHandler serves the admin LLM spend-ledger rollups at /api/v1/usage.
func NewUsageHandler ¶ added in v0.4.0
func NewUsageHandler(svc *usagesvc.Service) *UsageHandler
func (*UsageHandler) Get ¶ added in v0.4.0
func (h *UsageHandler) Get(w http.ResponseWriter, r *http.Request)
Get handles GET /api/v1/usage?days=N — the spend rollups over the last N days (N=0 means all time; default 30).
type UsersHandler ¶
type UsersHandler struct {
// contains filtered or unexported fields
}
func NewUsersHandler ¶
func NewUsersHandler(database *db.DB, usersSvc *userssvc.Service) *UsersHandler
func (*UsersHandler) Create ¶
func (h *UsersHandler) Create(w http.ResponseWriter, r *http.Request)
Create provisions a user with a temporary password (must_change_password is set by the service). Admin-gated via the service.
func (*UsersHandler) Delete ¶
func (h *UsersHandler) Delete(w http.ResponseWriter, r *http.Request)
Delete removes a user.
func (*UsersHandler) List ¶
func (h *UsersHandler) List(w http.ResponseWriter, r *http.Request)
List returns all users (admin-only — service gates on TenantUserManage).
func (*UsersHandler) ListSelectable ¶
func (h *UsersHandler) ListSelectable(w http.ResponseWriter, r *http.Request)
ListSelectable returns a slim user and built-in role-group directory for grantee picker dropdowns. Service gates on TenantUserView so any authenticated user can read it — resource and agent managers need the directory to share.
func (*UsersHandler) UpdateMe ¶ added in v0.4.0
func (h *UsersHandler) UpdateMe(w http.ResponseWriter, r *http.Request)
UpdateMe changes the authenticated user's display name.
func (*UsersHandler) UpdateRole ¶
func (h *UsersHandler) UpdateRole(w http.ResponseWriter, r *http.Request)
UpdateRole changes a user's tenant role.
type WSHandler ¶
type WSHandler struct {
// contains filtered or unexported fields
}
WSHandler upgrades HTTP connections to WebSocket.
func NewWSHandler ¶
func NewWSHandler(database *db.DB, hub *realtime.Hub, handler *realtime.Handler, jwtSecret, publicURL string, logger *zap.Logger) *WSHandler
NewWSHandler creates a new WebSocket upgrade handler.
func (*WSHandler) Upgrade ¶
func (h *WSHandler) Upgrade(w http.ResponseWriter, r *http.Request)
Upgrade handles GET /ws using the HttpOnly access cookie, upgrades to WebSocket, and auto-subscribes the connection to every agent the user holds an explicit per-user grant on (via agent_grants). The client does not issue subscribe messages; a DB-backed monitor closes the connection when its authorization or memberships change so reconnect rebuilds subscriptions.
Source Files
¶
- agent_exec_admin.go
- agent_sdk.go
- agents.go
- agents_git.go
- agents_source.go
- auth.go
- bridges.go
- catalog.go
- conv_mutex.go
- conversations.go
- credentials.go
- credentials_mcp.go
- device_login.go
- env_vars.go
- git_credentials.go
- grants.go
- health.go
- helpers.go
- identity.go
- integrations.go
- managed_bot_sessions.go
- middleware.go
- models.go
- needs.go
- oauth_server.go
- oauth_server_gc.go
- passkeys.go
- principal.go
- providers.go
- proxy.go
- realip.go
- relay.go
- resources.go
- router.go
- runs.go
- secured.go
- settings.go
- siblings.go
- sysagent.go
- tg_webapp.go
- usage.go
- user_sessions.go
- users.go
- webhook_git.go
- webhook_ingress.go
- ws.go