server

package
v0.0.1-nightly.2026101... Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 16, 2026 License: MPL-2.0 Imports: 49 Imported by: 0

Documentation

Overview

Package server is the HTTP layer: chi router, health surfaces, and the generated API. It never imports internal/store — enforced by the import-boundary test — so a handler cannot reach data except through the service layer, which authorizes inside a transaction.

Index

Constants

View Source
const (
	MaxInFlightRequests  = 512
	ResponseWriteTimeout = 60 * time.Second
	SSEWriteTimeout      = 30 * time.Second
	SSEHeartbeat         = 30 * time.Second
)

Transport bounds belong to the HTTP layer. Streaming handlers replace the ordinary response deadline with a fresh deadline for each complete frame.

View Source
const (
	MetricLastPruneSuccess       = "hikyo_last_prune_success_timestamp_seconds"
	MetricPruneStale             = "hikyo_prune_stale"
	MetricProjectStoragePeak     = "hikyo_project_storage_peak_bytes"
	MetricProjectStorageWarn     = "hikyo_project_storage_warn"
	MetricDataVolumeKnown        = "hikyo_data_volume_capacity_known"
	MetricDataVolumeUsedPercent  = "hikyo_data_volume_used_percent"
	MetricDataVolumeWarn         = "hikyo_data_volume_warn"
	MetricDataVolumeCritical     = "hikyo_data_volume_critical"
	MetricRootEscrowVerified     = "hikyo_root_escrow_verified"
	MetricRootEscrowVerifiedAt   = "hikyo_root_escrow_verified_timestamp_seconds"
	MetricRootRotationPending    = "hikyo_root_rotation_pending"
	MetricReencryptPendingScopes = "hikyo_reencrypt_pending_scopes"
	MetricLastReencryptSuccess   = "hikyo_last_reencrypt_success_timestamp_seconds"
	MetricPinsExpired            = "hikyo_pins_expired"
	MetricPinsExpiringDay        = "hikyo_pins_expiring_day"
	MetricPinsExpiringWeek       = "hikyo_pins_expiring_week"
	MetricPinsExpiringMonth      = "hikyo_pins_expiring_month"
	MetricTLSCertNotAfter        = "hikyo_tls_cert_not_after_timestamp_seconds"
	MetricTLSReloadFailures      = "hikyo_tls_reload_failures_total"

	// Deployment-adapter health (#157). Label-free by construction: they
	// count targets and jobs instance-wide and never name a tenant.
	MetricAdapterTargetsFailed    = "hikyo_adapter_targets_failed"
	MetricAdapterTargetsPaused    = "hikyo_adapter_targets_paused"
	MetricAdapterTargetsAttention = "hikyo_adapter_targets_attention"
	MetricAdapterJobsQueued       = "hikyo_adapter_jobs_queued"

	MetricRequestsTotal       = "hikyo_http_requests_total"
	MetricRequestErrors       = "hikyo_http_request_errors_total"
	MetricSignupMailFailures  = "hikyo_signup_mail_failures_total"
	MetricRequestsInFlight    = "hikyo_http_requests_in_flight"
	MetricRequestDuration     = "hikyo_http_request_duration_seconds"
	MetricMCPRequestsTotal    = "hikyo_mcp_requests_total"
	MetricMCPRequestsInFlight = "hikyo_mcp_requests_in_flight"
	MetricMCPRequestDuration  = "hikyo_mcp_request_duration_seconds"

	MetricAdmissionConcurrencyLimit = "hikyo_admission_concurrency_limit"
	MetricAdmissionInFlight         = "hikyo_admission_in_flight"
	MetricAdmissionQueueDepthLimit  = "hikyo_admission_queue_depth_limit"
	MetricAdmissionQueueWaiting     = "hikyo_admission_queue_waiting"
	MetricAdmissionActiveBackoffs   = "hikyo_admission_active_backoffs"

	// Multi-node HA gauges (#146). Label-free, so their cardinality is one each
	// regardless of cluster size (the ops-spec bounded-cardinality posture: no
	// per-node labels). On a single node they report the trivial values: this
	// node is the leader, one node is seen, and the lease age is zero.
	MetricHAIsLeader       = "hikyo_ha_is_leader"
	MetricHANodesSeen      = "hikyo_ha_nodes_seen"
	MetricHALeaseAgeSecond = "hikyo_ha_lease_age_seconds"

	// Secret-change approvals (#151). Label-free, bounded-cardinality gauges:
	// how many requests are awaiting review right now, and how many have expired
	// unmerged (a monotonic-ish operational signal that a policy's reviewers are
	// not keeping up). No per-tenant labels, so cardinality is one each.
	MetricApprovalRequestsOpen    = "hikyo_approval_requests_open"
	MetricApprovalRequestsExpired = "hikyo_approval_requests_expired"
	// MetricApprovalGaugesKnown is 1 when the two approval gauges above were
	// measured on this scrape and 0 when the source failed, in which case both
	// are omitted rather than rendered as zeros (a failed count is unknown,
	// not empty). Check it before alerting on either, like capacity_known.
	MetricApprovalGaugesKnown = "hikyo_approval_gauges_known"
	// Approval-mediated temporary access (#152). Label-free like the approval
	// gauges: open access requests awaiting a decision, and temporary grants
	// currently in force (granted requests whose absolute expiry is ahead).
	MetricAccessRequestsOpen = "hikyo_access_requests_open"
	MetricAccessGrantsActive = "hikyo_access_grants_active"
	// MetricAccessGaugesKnown is 1 when the two access gauges were measured on
	// this scrape; they are omitted when it is 0.
	MetricAccessGaugesKnown = "hikyo_access_gauges_known"
	// Disaster-recovery gauges (#145, ops-spec section 11). Label-free like
	// every other operator gauge: one series each, no archive name, no path.
	MetricLastBackupExportSuccess = "hikyo_last_backup_export_success_timestamp_seconds"
	MetricBackupRPOExceeded       = "hikyo_backup_rpo_exceeded"
	MetricLastBackupPruneSuccess  = "hikyo_last_backup_prune_success_timestamp_seconds"
	MetricLastRestoreDrill        = "hikyo_last_restore_drill_timestamp_seconds"
	MetricRestoreDrillOK          = "hikyo_restore_drill_ok"

	// Dynamic-secret gauges (#147). Label-free, cardinality one each. active is
	// the count of currently usable leases; effectsUnknown is the count of lease
	// transitions stuck in an uncertain state awaiting reconcile.
	MetricDynamicLeasesActive   = "hikyo_dynamic_leases_active"
	MetricDynamicEffectsUnknown = "hikyo_dynamic_effects_unknown"
	// MetricDynamicGaugesKnown is 1 when the two dynamic gauges above were
	// measured on this scrape and 0 when the source failed, in which case both
	// are omitted: a datastore outage must not read as "no unknown effects".
	MetricDynamicGaugesKnown = "hikyo_dynamic_gauges_known"
	// SSH certificate gauges (#155). Label-free, cardinality one each. active
	// counts issued, unexpired certificates; krl_entries counts the serials
	// every KRL currently publishes (bounded per CA by sshca.MaxKRLSerials).
	MetricSSHCertificatesActive = "hikyo_ssh_certificates_active"
	MetricSSHKRLEntries         = "hikyo_ssh_krl_entries"
	// MetricSSHGaugesKnown is 1 when the two SSH gauges were measured on this
	// scrape; 0 means they are omitted rather than rendered as zeros.
	MetricSSHGaugesKnown = "hikyo_ssh_gauges_known"
	// Transit (#156): live managed keys, keys whose rotation period has
	// elapsed, and keys waiting out their deletion delay. Label-free; the
	// known flag is 0 when the scrape could not measure them, and the three
	// value gauges are then omitted rather than rendered as zeros.
	MetricTransitKeysLive            = "hikyo_transit_keys_live"
	MetricTransitKeysRotationDue     = "hikyo_transit_keys_rotation_due"
	MetricTransitKeysPendingDeletion = "hikyo_transit_keys_pending_deletion"
	MetricTransitGaugesKnown         = "hikyo_transit_gauges_known"

	// Private-PKI gauges (#154). Label-free, cardinality one each: live leaf
	// certificates, certificates in the uncertain `unknown` state (published on
	// the CRL as revoked), and issuers held after a restore. The known flag has
	// the dynamic-gauge semantics: 0 means unmeasured, and the values are omitted.
	MetricPKICertificatesLive    = "hikyo_pki_certificates_live"
	MetricPKICertificatesUnknown = "hikyo_pki_certificates_unknown"
	MetricPKIIssuersOnHold       = "hikyo_pki_issuers_on_hold"
	MetricPKIGaugesKnown         = "hikyo_pki_gauges_known"

	// MetricSeriesBudget is the ops-spec ceiling for every registered series.
	MetricSeriesBudget = 1000
)

Metric family names. Exported so the conformance drift-guard can pin them: a rename here fails that test rather than silently breaking a dashboard.

View Source
const ContractPrefix = api.PathPrefix

ContractPrefix re-exports the version prefix so callers building URLs read it from the contract rather than restating it.

View Source
const MaxRequestBytes = 2 << 20

validateAgainstContract is the runtime request-validation duty: a request that does not satisfy api/openapi.yaml never reaches a handler, so the document is enforced rather than merely published. MaxRequestBytes bounds a request body before anything decodes it. Contract validation runs before the handler and before any pre-auth admission decision, so without this an unauthenticated client could make the server allocate an arbitrary amount of memory parsing JSON it was always going to reject. The bound is far above any legitimate request this contract describes.

Variables

This section is empty.

Functions

func New

func New(a *API, ui fs.FS) http.Handler

func NewMaintenance

func NewMaintenance(source RuntimeStatusSource, ui fs.FS, options PublicOptions) http.Handler

NewMaintenance exposes only public availability and static UI. It constructs no tenant API, auth service, workspace directory, or MCP handler.

func NewOperational

func NewOperational(ready ReadyChecker, healthService OperationalRetentionHealthService, metrics *Metrics) http.Handler

NewOperational builds the separate plaintext operational router. It carries no CORS or admission middleware and registers only local process surfaces.

metrics is the shared RED collector (#513). It is the SAME instance handed to the API middleware, so the scrape here reads the counters that middleware writes. A nil collector leaves /metrics as the retention/TLS gauges alone — the pre-#513 shape.

func NewPublic

func NewPublic(a *API, ui fs.FS, publicOptions PublicOptions) http.Handler

NewPublic builds the public router with explicit transport policy.

func RequestLatencyBucketsSeconds

func RequestLatencyBucketsSeconds() []float64

RequestLatencyBucketsSeconds returns a copy of the fixed histogram grid.

func WriteRuntimeUnavailable

func WriteRuntimeUnavailable(w http.ResponseWriter, r *http.Request)

WriteRuntimeUnavailable answers during the supervisor's brief global drain, before admission to any retiring graph. This instance-wide refusal does not inspect credentials or reveal whether a tenant/binding exists. Once routing resumes, SCIM refusals again rank behind normal binding authentication.

Types

type API

type API struct {
	Runtime      RuntimeStatusSource
	SelfConfig   *service.SelfConfig
	Mail         MailService
	Discovery    *service.Discovery
	Auth         AuthService
	SAMLAuth     SAMLAuthService
	Orgs         OrgService
	Projects     ProjectService
	Environments EnvironmentService
	Folders      FolderService
	Keys         KeyService
	Definitions  DefinitionsService
	Values       ValueService
	Revisions    RevisionService
	Rotation     RotationService
	Reencrypt    ReencryptService
	Pins         PinService
	Reveal       RevealService
	KeyGroups    KeyGroupService
	Grants       GrantService
	// Rules is the member access rule surface (member-access-rules ADR).
	Rules RuleService
	// Registration is the registration policy surface (#606) and the public
	// sign-up door `/auth/methods` renders.
	Registration         RegistrationService
	Identities           IdentityService
	DeveloperCredentials DeveloperCredentialService
	Federation           FederationService
	Delivery             DeliveryService
	Settings             SettingsService
	Retention            RetentionSettingsService
	RetentionHealth      OperationalRetentionHealthService
	Updates              UpdateService
	Providers            ProviderService
	OAuth2Providers      OAuth2ProviderService
	SAMLProviders        SAMLProviderService
	Adapters             *service.Adapters
	// FileTargets is the generic file-destination administration (#164).
	FileTargets *service.FileTargets
	// Dynamic is the dynamic-secret provider + lease surface (#147). Concrete
	// like Adapters: it resolves the session and mints/settles leases itself.
	Dynamic *service.Dynamic
	// SSH is the SSH user-certificate surface (#155).
	SSH *service.SSH
	// Transit is the managed-key surface (#156). Concrete like Dynamic: it
	// resolves the caller and applies key policy itself.
	Transit *service.Transit
	// PKI is the private-PKI surface (#154).
	PKI *service.PKI
	// Audits is the trail read/export surface. Concrete like Adapters: it is
	// principal-keyed and the handler resolves the session before calling it.
	Audits *service.Audits
	// Approvals is the change-approval administration and review surface (#151).
	// The merge/bypass DECISION rides Revisions.PublishPlanned, not this.
	Approvals ApprovalService
	// Access is the approval-mediated temporary-access surface (#152).
	Access AccessService
	// SCIM is the provisioning ADMINISTRATION surface (human sessions,
	// `manage-members` at org scope); SCIMWire is the identity provider's own
	// protocol path (a provisioning credential, `scim-provision`). They are two
	// fields rather than one because they are two authorization languages, and
	// a single interface would let a handler reach the wrong one by autocomplete.
	SCIM     SCIMAdminService
	SCIMWire SCIMWireService
	// Multi-instance (#71): the viewing side's directory and the serving
	// side's connections, allowlist, handoff and session surface.
	Remotes   RemoteService
	Workspace WorkspaceService
	// Admission bounds the unauthenticated discovery endpoint. The expensive
	// pre-auth paths take their own slot inside the service, where the cost
	// they bound actually lives; /meta is cheap and only needs a per-IP
	// ceiling, so it is charged here. Nil means unlimited, which is only for
	// tests.
	Admission *admission.Limiter
	// RequestBudget charges authenticated human requests at the service's
	// transaction-local admission hook, never from a guessed wire subject.
	RequestBudget *service.Budget
	// Metrics is the shared RED collector (#513). The same instance is handed to
	// NewOperational so the /metrics reader and this middleware's writer see one
	// set of counters. Nil disables collection (tests), leaving the access log
	// and handler behaviour unchanged.
	Metrics *Metrics
	Version string
	Log     *slog.Logger
	// TrustedProxies are the CIDRs whose forwarded headers are believed.
	// Empty means none: proxy trust is explicit configuration, never
	// inferred, because an unauthenticated header is not evidence.
	TrustedProxies []*net.IPNet
}

API implements the generated strict server.

func (*API) AuthMethods

AuthMethods returns public login methods and the sign-up door for the requested org, or the instance when no org is supplied. An unknown or empty org selects a closed door. Discovery throttling returns 429; service and conversion failures become 500 responses.

func (*API) CancelAccessRequest

CancelAccessRequest withdraws the addressed request and returns it as JSON, propagating service errors.

func (*API) ChangeTransitKeyState

ChangeTransitKeyState applies a lifecycle action with an optional deletion delay in seconds. Delay validation, service, and response conversion errors propagate to the HTTP error handler.

func (*API) ConfigureTransitKey

ConfigureTransitKey applies supplied policy fields and returns updated metadata. Version validation, service, and response conversion errors propagate.

func (*API) CreateAccessPolicy

CreateAccessPolicy creates a policy in the addressed project and returns it as JSON, propagating service errors.

func (*API) CreateAccessRequest

CreateAccessRequest files an environment request and returns it as JSON, propagating service errors.

func (*API) CreateTransitKey

CreateTransitKey creates a key and returns its metadata with status 201. Service and response conversion errors propagate to the HTTP error handler.

func (*API) DeleteAccessPolicy

DeleteAccessPolicy deletes the addressed policy and returns a no-content response, propagating service errors.

func (*API) EmergencyAccess

EmergencyAccess asks the service for emergency access in the addressed environment and returns the request as JSON, propagating service errors.

func (*API) GetMyProfile

GetMyProfile returns the authenticated account profile over the API.

func (*API) GetOrg

GetOrg reads one organisation. It is tenant-scoped at org depth (#48), so there is no 403 leg: a caller who may not reach the org gets the same 404 as one asking after an org that never existed. The refusal is rendered by the uniform writer through the strict server's error leg, like the rest of the hierarchy surface — see internal/server/hierarchy.go.

func (*API) GetTotpStatus

GetTotpStatus reports the caller's own authenticator state. A pure read on the caller's account, classified like ListPasskeys: no MFA gate, no mutation.

func (*API) InviteInstanceMember

InviteInstanceMember is the instance-scope form: the same transaction under `manage-members` held at instance scope.

func (*API) InviteOrgMember

InviteOrgMember is the human-auth ADR's account-creation path at organisation scope. The authority is delivered in the HTTP response to the inviter, who hands it to the invitee out of band — the same delivery credential-reset uses. Every refusal goes through the one uniform writer: a taken username is the store's conflict, an unauthorized caller the tenant class's uniform 403/404.

func (*API) IssueCertificate

IssueCertificate returns the public certificate and, for generated-key issuance, its display-once private key. It zeroes the service's key buffer after copying it into the response. Conversion and service errors propagate.

func (*API) LinkIdentity

LinkIdentity starts a session-bound OIDC linking ceremony using the caller's proof. A browser start sets a return marker cookie; service errors propagate.

func (*API) ListAccessPolicies

ListAccessPolicies returns the addressed project's policies as a JSON list, propagating service errors.

func (*API) ListAccessRequests

ListAccessRequests returns the environment's request queue and covering offer as JSON, omitting the offer when absent and propagating service errors.

func (*API) ListMyOrgs

ListMyOrgs is the navigation surface: the organisations the caller's own grants name. Distinct from ListOrgs, which is the operator's enumeration of every org and is MFA-mandatory — see the contract and service for why the sidebar must not go through it.

func (*API) ListOrgs

ListOrgs enumerates organizations for an authorized operator. An origin query narrows the returned items and count after the service read; list authorization and read errors propagate.

func (*API) ListRevisions

ListRevisions is one page of lineage. The contract validator has already bounded `limit` to the spec's range, so the defaults here are the only interpretation left: no cursor means "from the newest", no limit means the documented default page. `next_before` appears exactly when the page was full, so a client that pages until it is absent reads the whole history.

func (*API) ListTransitKeys

ListTransitKeys returns the environment's key metadata. Service and response conversion errors propagate to the HTTP error handler.

func (*API) LoginChallengeTotp

LoginChallengeTotp satisfies a login challenge with a TOTP code and mints the browser session (#760). Refusals map through the shared wire policy exactly as stepUpTotp does: a missing/expired/consumed challenge is 404, a wrong code 401, a replayed time step 409, the factor budget 429.

func (*API) Middleware

func (a *API) Middleware() []func(http.Handler) http.Handler

Middleware returns the matched-route API stack, outermost first. recoverPanics leads the error-contract legs so an invariant panic below becomes the uniform refusal. RED observation lives at public-router scope so it also sees unmatched API paths, unsupported methods, and CORS preflights — see internal/server/server.go and metrics.go.

func (*API) Oauth2Start

Oauth2Start forwards the purpose, login intent and optional sign-up org to the service. A successful anonymous start sets the browser-binding cookie; its expected refusals are rendered by oauth2StartError.

func (*API) OidcStart

OidcStart forwards the purpose, login intent and optional sign-up org to the service. A successful anonymous start sets the browser-binding cookie; its expected refusals are rendered by oidcStartError.

func (*API) ReauthTotp

ReauthTotp opens a disclosure window with a TOTP code.

The one refusal worth reading twice is the 409. A `0` effective window — what every protected environment is capped at — has no TOTP path at all, because TOTP cannot bind its challenge to the enumerated unit and therefore cannot authorize one decision over exactly those keys. That is not an authorization answer about this caller, it is the ENVIRONMENT's state refusing the factor, which is what conflict means. Answering 401 instead would tell the human their code was wrong and send them to re-enrol an authenticator that was never the problem.

func (*API) RemoveWorkspaceOrigin

RemoveWorkspaceOrigin takes the origin in the BODY, never in the path. A path parameter naming an origin is one review lapse away from a path parameter naming a target, and api/noproxy_test.go refuses that shape by name.

func (*API) ResetCredential

Administrator-issued credential reset (#54, human-auth ADR - Recovery).

The route is enumeration-uniform (classified unauthenticated): every failure that could reveal the target's grant shape — an unknown target, a caller lacking credential-reset, an org-P holder reaching for an org-O target, and a target holding an instance capability (break-glass only) — answers the same uniform 401 (B2). There is no differential status a reset holder could probe grant shapes with; the operator learns to use break-glass from the docs, and the true cause of every refusal is durable in the audit trail.

func (*API) RevokeAccessRequest

RevokeAccessRequest ends the addressed granted access and returns the request as JSON, propagating service errors.

func (*API) RotateTransitKey

RotateTransitKey appends a key version and returns updated metadata. Service and response conversion errors propagate to the HTTP error handler.

func (*API) ScimResourceTypes

The two documents that describe SCHEMAS are per-binding: they render the extensions THIS binding declared, which is the same closed set ingest enforces and a rendered resource may name.

func (*API) SetValue

SetValue and ClearValue STAGE. Neither publishes, so neither answers with a value cell: what they return is the immutable version id a later selective publish names, which is the only thing the caller can act on.

func (*API) ShowTransitKey

ShowTransitKey returns metadata for the named key. Service and response conversion errors propagate to the HTTP error handler.

func (*API) SlideSessionClocks

func (a *API) SlideSessionClocks(next http.Handler) http.Handler

SlideSessionClocks is the post-response idle-clock touch. It runs after the handler so a write never sits between authorization and the answer, and it is rate-limited by granularity inside the service so an authenticated GET storm does not become a write storm.

func (*API) TransitDataKey

TransitDataKey returns a wrapped data key and, when requested, standard-base64 plaintext. The plaintext buffer is zeroed after encoding. Context decoding and service errors propagate.

func (*API) TransitDecrypt

TransitDecrypt returns standard-base64 plaintext and its key version, zeroing the decoded plaintext buffer after encoding. Context decoding and service errors propagate.

func (*API) TransitEncrypt

TransitEncrypt decodes standard-base64 plaintext and context and returns versioned ciphertext. The decoded plaintext is zeroed on return; decoding, version validation, and service errors propagate.

func (*API) TransitHMAC

TransitHMAC decodes a standard-base64 message and returns a versioned MAC. Decoding, version validation, and service errors propagate.

func (*API) TransitRewrap

TransitRewrap returns ciphertext under the latest permitted key version without returning plaintext. Context decoding and service errors propagate.

func (*API) TransitSign

TransitSign decodes a standard-base64 message and returns a versioned signature. Decoding, version validation, and service errors propagate.

func (*API) TransitVerify

TransitVerify returns the signature verification result and key version. A mismatch returns Valid=false with status 200; decoding and service errors propagate to the HTTP error handler.

func (*API) TransitVerifyHMAC

TransitVerifyHMAC returns the MAC verification result and key version. A mismatch returns Valid=false with status 200; decoding and service errors propagate to the HTTP error handler.

func (*API) TrimTransitKey

TrimTransitKey removes eligible old versions and returns the key metadata and deletion count. Service and response conversion errors propagate.

func (*API) UpdateAccessPolicy

UpdateAccessPolicy replaces the addressed policy and returns it as JSON, propagating service errors.

func (*API) UpdateKeyMetadata

UpdateKeyMetadata writes the four non-semantic fields — and refuses a body that carries `classification` at all, equal to the current value or not. Refusing the FIELD rather than the CHANGE is deliberate: it needs no read, and it keeps a caller from discovering the current classification by observing which values are accepted.

func (*API) UpdateMyProfile

UpdateMyProfile applies editable names without accepting email changes.

func (*API) VoteAccessRequest

VoteAccessRequest submits an approve or reject decision and returns the request as JSON, propagating service errors.

func (*API) WatchProjectEvents

WatchProjectEvents streams the advisory channel.

The events arrive already authorized and already projected -- the service evaluates the per-event, per-object check before anything reaches this channel -- so this function does transport and nothing else: headers, framing, flushing, heartbeats, and giving up when the peer goes away.

type AccessService

type AccessService interface {
	ListPolicies(ctx context.Context, actor service.Actor, scope domain.Scope) ([]service.AccessPolicyView, error)
	CreatePolicy(ctx context.Context, actor service.Actor, scope domain.Scope, input service.AccessPolicyInput) (service.AccessPolicyView, error)
	UpdatePolicy(ctx context.Context, actor service.Actor, scope domain.Scope, id string, input service.AccessPolicyInput) (service.AccessPolicyView, error)
	DeletePolicy(ctx context.Context, actor service.Actor, scope domain.Scope, id string) error
	Queue(ctx context.Context, actor service.Actor, scope domain.Scope) (service.AccessQueue, error)
	Request(ctx context.Context, actor service.Actor, scope domain.Scope, input service.AccessRequestInput) (service.AccessRequestView, error)
	Vote(ctx context.Context, actor service.Actor, scope domain.Scope, requestID, decision string) (service.AccessRequestView, error)
	Cancel(ctx context.Context, actor service.Actor, scope domain.Scope, requestID string) (service.AccessRequestView, error)
	Revoke(ctx context.Context, actor service.Actor, scope domain.Scope, requestID string) (service.AccessRequestView, error)
	EmergencyAccess(ctx context.Context, actor service.Actor, scope domain.Scope, input service.AccessRequestInput) (service.AccessRequestView, error)
}

AccessService is the domain surface this transport exposes.

type AccessSnapshotter

type AccessSnapshotter interface {
	AccessSnapshot() (open, active int64, err error)
}

AccessSnapshotter supplies the temporary-access gauges at scrape time (#152). Same contract as ApprovalSnapshotter: quick, non-blocking, and an error marks the gauges unknown for this scrape.

type AdmissionSnapshotter

type AdmissionSnapshotter interface {
	Snapshot() admission.Snapshot
}

AdmissionSnapshotter is the admission-pressure source the gauges read at scrape time. Nil renders zeros, so the exposition shape stays deterministic whether or not a limiter is wired.

type ApprovalService

type ApprovalService interface {
	ListPolicies(ctx context.Context, actor service.Actor, scope domain.Scope) ([]service.ApprovalPolicyView, error)
	CreatePolicy(ctx context.Context, actor service.Actor, scope domain.Scope, input service.ApprovalPolicyInput) (service.ApprovalPolicyView, error)
	UpdatePolicy(ctx context.Context, actor service.Actor, scope domain.Scope, id string, input service.ApprovalPolicyInput) (service.ApprovalPolicyView, error)
	DeletePolicy(ctx context.Context, actor service.Actor, scope domain.Scope, id string) error
	ListRequests(ctx context.Context, actor service.Actor, scope domain.Scope) ([]service.ApprovalRequestView, error)
	CeremonyBinding(ctx context.Context, actor service.Actor, scope domain.Scope, requestID string) (service.ApprovalCeremonyBinding, error)
	Vote(ctx context.Context, actor service.Actor, scope domain.Scope, requestID string, decision string) (service.ApprovalRequestView, error)
}

ApprovalService is the domain surface this transport exposes.

type ApprovalSnapshotter

type ApprovalSnapshotter interface {
	ApprovalSnapshot() (ApprovalStats, error)
}

ApprovalSnapshotter supplies the approval gauges at scrape time. It is read synchronously in Collect, so an implementation must be quick and must not block. An error marks the gauges unknown for this scrape: the collector omits them and renders MetricApprovalGaugesKnown as 0 instead of failing the scrape or inventing zeros.

type ApprovalStats

type ApprovalStats struct {
	Open    float64
	Expired float64
}

ApprovalStats is the label-free approval snapshot (#151): active requests awaiting review, and requests that have expired unmerged.

type AuthService

type AuthService interface {
	StartCLILogin(ctx context.Context, transport, state, challenge, redirect string) (service.CLILoginStart, error)
	CLILoginTransaction(ctx context.Context, actor service.Actor, reference string) (service.CLILoginTransaction, error)
	ApproveCLILogin(ctx context.Context, actor service.Actor, reference string) (service.CLIReauthApproval, error)
	RedeemCLILogin(ctx context.Context, code, verifier, redirect string) (service.LoginResult, error)
	PollCLIDevice(ctx context.Context, code string) (service.CLIDeviceAttempt, error)

	OAuth2Start(ctx context.Context, slug, purpose, intent, signupOrg, environmentID, presented, proof string, browser bool) (service.OIDCStartResult, error)
	OAuth2Callback(ctx context.Context, slug, code, state, iss, idpError, bindingCookie, presented string) (service.OIDCCallbackResult, error)
	Signup(ctx context.Context, email string, org domain.OrgID) error
	VerifySignup(ctx context.Context, in service.SignupVerification) error
	MyProfile(ctx context.Context, presented string) (service.AccountProfile, error)
	UpdateMyProfile(ctx context.Context, presented string, profile service.ProfileUpdate, proof string) (service.AccountProfile, error)
	LocalLogin(ctx context.Context, username, password string, artifact service.Artifact) (service.LoginResult, error)
	LoginChallengeTOTP(ctx context.Context, challengeID, code string) (service.LoginResult, error)
	LoginChallengeWebauthnStart(ctx context.Context, challengeID string) ([]byte, error)
	LoginChallengeWebauthnFinish(ctx context.Context, challengeID string, responseJSON []byte) (service.LoginResult, error)
	EstablishCredential(ctx context.Context, authority, password string) error
	SetPassword(ctx context.Context, presented, password, proof string) (service.LoginResult, error)
	Identity(ctx context.Context, presented string) (service.Identity, error)
	Logout(ctx context.Context, presented string) error
	VerifyBrowserCSRF(ctx context.Context, presented, csrfToken string) error
	SlideIdleClock(ctx context.Context, presented string, activity service.CallerActivity) error
	EnrolTOTPStart(ctx context.Context, presented, password string) (string, error)
	EnrolTOTPConfirm(ctx context.Context, presented, code string) (service.LoginResult, error)
	StepUpTOTP(ctx context.Context, presented, code string) (service.LoginResult, error)
	RemoveTOTP(ctx context.Context, presented, password string) (service.LoginResult, error)
	TOTPStatus(ctx context.Context, presented string) (service.TOTPStatusResult, error)
	GenerateRecoveryCodes(ctx context.Context, presented, proof string) ([]string, service.LoginResult, error)
	ConsumeRecoveryCode(ctx context.Context, username, code string) (service.RecoveryResult, error)
	AuthMethods(ctx context.Context) ([]service.AuthMethodProvider, bool, error)
	OIDCStart(ctx context.Context, slug, purpose, intent, signupOrg, environmentID, presented, proof string, browser bool) (service.OIDCStartResult, error)
	OIDCCallback(ctx context.Context, slug, code, state, iss, idpError, bindingCookie, presented string) (service.OIDCCallbackResult, error)
	ListIdentities(ctx context.Context, presented string) ([]authnIdentity, error)
	UnlinkIdentity(ctx context.Context, presented, identityID, proof string) (service.LoginResult, error)
	EnrolPasskeyStart(ctx context.Context, presented, password, code string) ([]byte, error)
	EnrolPasskeyFinish(ctx context.Context, presented string, responseJSON []byte) (service.LoginResult, error)
	PasskeyLoginStart(ctx context.Context) ([]byte, error)
	PasskeyLoginFinish(ctx context.Context, responseJSON []byte) (service.LoginResult, error)
	StepUpPasskeyStart(ctx context.Context, presented string) ([]byte, error)
	StepUpPasskeyFinish(ctx context.Context, presented string, responseJSON []byte) (service.LoginResult, error)
	ReauthPasskeyStart(ctx context.Context, presented string, intent service.ReauthIntent) ([]byte, error)
	ReauthPasskeyFinish(ctx context.Context, presented string, responseJSON []byte) (service.ReauthResult, error)
	ReauthTOTP(ctx context.Context, presented string, intent service.ReauthIntent, code string) (service.ReauthResult, error)
	ReauthAdapterTOTP(ctx context.Context, presented string, intent service.ReauthIntent, code string) ([]service.ReauthResult, error)
	StartCLIReauth(ctx context.Context, presented string, intent service.ReauthIntent, pkceChallenge, redirectURI string) (service.CLIReauthStart, error)
	CLIReauthTransaction(ctx context.Context, actor service.Actor, state string) (service.CLIReauthTransaction, error)
	ApproveCLIReauth(ctx context.Context, actor service.Actor, state string) (service.CLIReauthApproval, error)
	RedeemCLIReauth(ctx context.Context, code, pkceVerifier string) (service.CLIReauthRedeemed, error)
	RemovePasskey(ctx context.Context, presented, credentialID, password, code string) (service.LoginResult, error)
	ListPasskeys(ctx context.Context, presented string) ([]service.PasskeyView, error)
	ResetCredential(ctx context.Context, actor service.Actor, targetPrincipal, delivery string) (service.ResetResult, error)
}

AuthService is the human-authentication surface this transport needs.

type DefinitionsService

type DefinitionsService interface {
	Export(ctx context.Context, actor service.Actor, scope domain.Scope, portable bool) ([]byte, error)
	Check(ctx context.Context, actor service.Actor, scope domain.Scope, raw []byte) (service.CheckResult, error)
	Plan(ctx context.Context, actor service.Actor, scope domain.Scope, raw []byte, acks []string) (service.PlanView, error)
	GetPlan(ctx context.Context, actor service.Actor, scope domain.Scope, planID string) (service.PlanView, error)
	Apply(ctx context.Context, actor service.Actor, scope domain.Scope, planID string, opts service.ApplyOptions) (service.ApplyResult, error)
	GetSettings(ctx context.Context, actor service.Actor, scope domain.Scope) (service.DefinitionsSettings, error)
	SetSettings(ctx context.Context, actor service.Actor, scope domain.Scope, source string) (service.DefinitionsSettings, error)
}

DefinitionsService is the project definitions Git-flow surface. Bundle inputs remain raw bytes through transport so the strict parser can detect duplicate members and enforce its own byte bound without a lossy re-encode.

type DeliveryService

type DeliveryService interface {
	Fetch(ctx context.Context, presented string, scope domain.Scope, cursor string, opts service.FetchOptions) (service.FetchResult, error)
	ReconcileOfflineRecords(ctx context.Context, presented string, scope domain.Scope, records []service.OfflineRecord) (service.ReconcileResult, error)
	ReportTarget(ctx context.Context, presented string, scope domain.Scope, report deliverytarget.Report) error
	TombstoneTarget(ctx context.Context, presented string, scope domain.Scope, key service.DeliveryTargetKey) error
	RefuseOversizeReport(ctx context.Context, presented string, scope domain.Scope) error
	ListTargets(ctx context.Context, actor service.Actor, scope domain.Scope) (service.DeliveryTargetList, error)
	ReportFileTarget(ctx context.Context, presented string, scope domain.Scope, targetID string, report service.FileTargetReport) error
}

DeliveryService is the domain surface this transport exposes.

type DeveloperCredentialService

DeveloperCredentialService preserves the raw presented human artifact. The service owns self-delegation, live authorization, reauthentication and policy.

type DynamicSnapshotter

type DynamicSnapshotter interface {
	DynamicSnapshot() (activeLeases, unknownEffects int64, err error)
}

DynamicSnapshotter is the dynamic-secret gauge source, read at scrape time. An error (or a nil source) marks the gauges unknown for this scrape: the collector omits them and renders MetricDynamicGaugesKnown as 0, so a datastore hiccup never reads as a measured zero.

type EnvironmentService

type EnvironmentService interface {
	Parameters(context.Context, service.Actor, domain.Scope) (map[string]string, error)
	SetParameter(context.Context, service.Actor, domain.Scope, string, string, bool) error
	Create(ctx context.Context, actor service.Actor, scope domain.Scope, name string, acks []string) (service.Environment, error)
	// Clone is create-with-clone-at-creation (#50). It is a separate method
	// because its RESULT is different: a clone reports what it could not take.
	Clone(ctx context.Context, actor service.Actor, scope domain.Scope, name, sourceEnvID string, acks []string) (service.Environment, service.CloneResult, error)
	Get(ctx context.Context, actor service.Actor, scope domain.Scope) (service.Environment, error)
	List(ctx context.Context, actor service.Actor, scope domain.Scope) ([]service.Environment, error)
	Rename(ctx context.Context, actor service.Actor, scope domain.Scope, name string, acks []string) (service.Environment, error)
	Reorder(ctx context.Context, actor service.Actor, scope domain.Scope, ordered []string) ([]service.Environment, error)
	Delete(ctx context.Context, actor service.Actor, scope domain.Scope) error
}

type FederationService

type FederationService interface {
	CreateIssuer(ctx context.Context, actor service.Actor, req service.IssuerRequest) (service.IssuerView, error)
	UpdateIssuer(ctx context.Context, actor service.Actor, id string, source jwkssource.KeySource, refused []string, caBundle *string) (service.IssuerView, error)
	ListIssuers(ctx context.Context, actor service.Actor) ([]service.IssuerView, error)
	DeleteIssuer(ctx context.Context, actor service.Actor, id string) error
	CreateBinding(ctx context.Context, actor service.Actor, scope domain.Scope, saID string, req service.BindingRequest) (service.BindingView, error)
}

FederationService is the domain surface this transport exposes.

type FolderService

type FolderService interface {
	Create(ctx context.Context, actor service.Actor, scope domain.Scope, path string, acks []string) (service.Folder, error)
	Get(ctx context.Context, actor service.Actor, scope domain.Scope, id string) (service.Folder, error)
	List(ctx context.Context, actor service.Actor, scope domain.Scope) ([]service.Folder, error)
	Rename(ctx context.Context, actor service.Actor, scope domain.Scope, id, path string, acks []string) (service.Folder, error)
	Delete(ctx context.Context, actor service.Actor, scope domain.Scope, id string) error
}

type GrantService

type GrantService interface {
	Create(ctx context.Context, actor service.Actor, spec service.GrantSpec) (service.GrantResult, error)
	Revoke(ctx context.Context, actor service.Actor, spec service.GrantSpec) error
	List(ctx context.Context, actor service.Actor, scope domain.Scope) ([]service.Membership, error)
	ApplyTemplate(ctx context.Context, actor service.Actor, template domain.Template, principal domain.PrincipalID, scope domain.Scope) ([]service.GrantResult, error)
	InviteMember(ctx context.Context, actor service.Actor, spec service.InviteSpec) (service.InvitationResult, error)
}

GrantService is the domain surface this transport exposes.

type HASnapshotter

type HASnapshotter interface {
	HASnapshot() HAStats
}

HASnapshotter is the HA-state source the gauges read at scrape time. A nil source renders the single-node defaults, so the exposition shape is deterministic whether or not HA is wired.

type HAStats

type HAStats struct {
	Enabled         bool
	IsLeader        bool
	NodesSeen       int
	LeaseAgeSeconds float64
}

HAStats is a point-in-time read of multi-node HA state for the label-free gauges. Enabled is false on a single node, where the collector emits the trivial values (leader, one node, zero lease age).

type IdentityService

type IdentityService interface {
	CreateServiceAccount(ctx context.Context, actor service.Actor, scope domain.Scope, name string, kind domain.PrincipalClass) (service.ServiceAccountView, error)
	ListServiceAccounts(ctx context.Context, actor service.Actor, scope domain.Scope) ([]service.ServiceAccountView, error)
	DeleteServiceAccount(ctx context.Context, actor service.Actor, scope domain.Scope, id string) error
	MintCredential(ctx context.Context, actor service.Actor, scope domain.Scope, saID string, req service.MintRequest) (service.MintResult, error)
	ListCredentials(ctx context.Context, actor service.Actor, scope domain.Scope, saID string) ([]service.CredentialView, error)
	RevokeCredential(ctx context.Context, actor service.Actor, scope domain.Scope, saID, credentialID string) error
	Policy(ctx context.Context, actor service.Actor) (service.PolicyView, error)
	SetPolicy(ctx context.Context, actor service.Actor, change service.PolicyChange) (service.PolicyResult, error)
}

IdentityService is the domain surface this transport exposes.

type KeyGroupService

type KeyGroupService interface {
	Create(ctx context.Context, actor service.Actor, scope domain.Scope, name string, acks []string) (service.KeyGroupView, error)
	Get(ctx context.Context, actor service.Actor, scope domain.Scope, id string) (service.KeyGroupView, error)
	List(ctx context.Context, actor service.Actor, scope domain.Scope) ([]service.KeyGroupView, error)
	Rename(ctx context.Context, actor service.Actor, scope domain.Scope, id, name string, acks []string) (service.KeyGroupView, error)
	Delete(ctx context.Context, actor service.Actor, scope domain.Scope, id string) error
}

type KeyService

type KeyService interface {
	Create(ctx context.Context, actor service.Actor, scope domain.Scope, spec service.KeySpec, acks []string) (service.Key, error)
	Get(ctx context.Context, actor service.Actor, scope domain.Scope, id string) (service.Key, error)
	List(ctx context.Context, actor service.Actor, scope domain.Scope) ([]service.Key, int64, error)
	Rename(ctx context.Context, actor service.Actor, scope domain.Scope, id, name string, acks []string) (service.Key, error)
	UpdateMetadata(ctx context.Context, actor service.Actor, scope domain.Scope, id string, m service.KeyMetadataUpdate, acks []string) (service.Key, error)
	UpdateDeclaration(ctx context.Context, actor service.Actor, scope domain.Scope, id string, u service.KeyDeclarationUpdate, acks []string) (service.Key, error)
	Reclassify(ctx context.Context, actor service.Actor, scope domain.Scope, id, classification string) (service.Key, []service.Finding, error)
	SetGroup(ctx context.Context, actor service.Actor, scope domain.Scope, id, groupID string) (service.Key, error)
	Delete(ctx context.Context, actor service.Actor, scope domain.Scope, id string) error
}

KeyService and KeyGroupService are the domain surfaces this transport exposes. Scopes are addressed as domain.Scope, the same shape authorize() takes, so a wrong-depth address is refused at the chokepoint.

type MailService

type MailService interface {
	Configured(context.Context, service.Actor) (bool, error)
	Test(context.Context, service.Actor, string, string) error
}

type Metrics

type Metrics struct {
	// contains filtered or unexported fields
}

Metrics is the instance-wide RED collector. One instance is shared between the API middleware (which writes) and the operational /metrics handler (which reads), so both sides see the same counters.

func NewMetrics

func NewMetrics(adm AdmissionSnapshotter) *Metrics

NewMetrics builds the fixed collector set in a private pedantic registry. Pre-creating every closed label combination keeps the scrape shape deterministic even before traffic arrives.

func (*Metrics) ObserveMCP

func (m *Metrics) ObserveMCP(next http.Handler, log *slog.Logger, toolNames []string) http.Handler

ObserveMCP wraps the feature-gated MCP handler with closed-cardinality metrics and debug access logs. toolNames must come from the compiled registry. Request-controlled method and tool strings collapse to "other".

func (*Metrics) RecordSignupMailFailure

func (m *Metrics) RecordSignupMailFailure()

RecordSignupMailFailure exposes a hidden synchronous delivery failure. The request counter preserves its wire 202; RED errors use the operational 5xx fault category, as recovered faults after committed headers already do. No address, policy, intent, or SMTP response enters the metric label set.

func (*Metrics) SetAccessSource

func (m *Metrics) SetAccessSource(source AccessSnapshotter)

SetAccessSource attaches the temporary-access gauge source once at boot.

func (*Metrics) SetApprovalSource

func (m *Metrics) SetApprovalSource(source ApprovalSnapshotter)

SetApprovalSource attaches the approval gauge source after registration, via an atomic pointer, so boot can wire it without racing a concurrent scrape.

func (*Metrics) SetDynamicSource

func (m *Metrics) SetDynamicSource(source DynamicSnapshotter)

SetDynamicSource attaches the dynamic-secret gauge source once at boot.

func (*Metrics) SetHASource

func (m *Metrics) SetHASource(source HASnapshotter)

SetHASource attaches the multi-node HA gauge source. It is called once during boot before the operational listener serves, so the collector's source pointer is set before any scrape reads it.

func (*Metrics) SetPKISource

func (m *Metrics) SetPKISource(source PKISnapshotter)

SetPKISource attaches the private-PKI gauge source once at boot.

func (*Metrics) SetSSHSource

func (m *Metrics) SetSSHSource(source SSHSnapshotter)

SetSSHSource attaches the SSH certificate gauge source once at boot.

func (*Metrics) SetTransitSource

func (m *Metrics) SetTransitSource(source TransitSnapshotter)

SetTransitSource attaches the transit gauge source once at boot.

type OAuth2ProviderService

type OAuth2ProviderService interface {
	Put(ctx context.Context, actor service.Actor, slug string, in service.OAuth2ProviderInput) (service.OAuth2ProviderView, error)
	Get(ctx context.Context, actor service.Actor, slug string) (service.OAuth2ProviderView, error)
	List(ctx context.Context, actor service.Actor) ([]service.OAuth2ProviderView, error)
	Delete(ctx context.Context, actor service.Actor, slug string) error
}

type OperationalRetentionHealthService

type OperationalRetentionHealthService interface {
	OperationalHealth(ctx context.Context) (service.PruneHealth, error)
}

type OrgService

type OrgService interface {
	Create(ctx context.Context, actor service.Actor, name string, active bool, metadata json.RawMessage) (org service.Org, err error)
	Get(ctx context.Context, actor service.Actor, org domain.OrgID) (service.Org, error)
	List(ctx context.Context, actor service.Actor) ([]service.Org, error)
	ListMine(ctx context.Context, actor service.Actor) ([]service.MyOrg, error)
	Rename(ctx context.Context, actor service.Actor, org domain.OrgID, name string) (service.Org, error)
	Delete(ctx context.Context, actor service.Actor, org domain.OrgID) error
}

OrgService is the domain surface this slice exposes.

Every method takes a service.Actor, never a principal id: the transport hands over the RAW artifact and the service resolves it inside the transaction that authorizes the operation. Resolving here and passing an id would put the decision about who the caller is on one side of a transaction boundary and the authorization that trusts it on the other — a session revoked in between would still authorize the operation. That is the cross-request cache the permission model forbids, wearing an argument's clothes.

type PKISnapshotter

type PKISnapshotter interface {
	PKISnapshot() (live, unknown, held int64, err error)
}

PKISnapshotter is the private-PKI gauge source, read at scrape time, with the DynamicSnapshotter failure semantics.

type PinService

type PinService interface {
	Set(ctx context.Context, actor service.Actor, scope domain.Scope, request service.SetPinRequest) (service.SetPinResult, error)
	List(ctx context.Context, actor service.Actor, scope domain.Scope) ([]service.PinView, error)
	Release(ctx context.Context, actor service.Actor, scope domain.Scope, workloadPrincipalID domain.PrincipalID) (service.ReleasePinResult, error)
}

type ProjectService

type ProjectService interface {
	Create(ctx context.Context, actor service.Actor, org domain.OrgID, name string) (service.Project, error)
	Get(ctx context.Context, actor service.Actor, scope domain.Scope) (service.Project, error)
	List(ctx context.Context, actor service.Actor, org domain.OrgID) ([]service.Project, error)
	Rename(ctx context.Context, actor service.Actor, scope domain.Scope, name string) (service.Project, error)
	Delete(ctx context.Context, actor service.Actor, scope domain.Scope) error
}

ProjectService, EnvironmentService and FolderService are the domain surfaces this transport exposes. Scopes are addressed as domain.Scope — the same shape authorize() takes — so a wrong-depth address is refused at the chokepoint rather than silently widened here.

type ProviderService

type ProviderService interface {
	Put(ctx context.Context, actor service.Actor, slug string, in service.ProviderInput) (service.ProviderView, error)
	Get(ctx context.Context, actor service.Actor, slug string) (service.ProviderView, error)
	List(ctx context.Context, actor service.Actor) ([]service.ProviderView, error)
	Delete(ctx context.Context, actor service.Actor, slug string) error
}

ProviderService is the OIDC provider administration surface.

type PublicOptions

type PublicOptions struct {
	HSTS bool
	// ExternalOrigin is the config-validated canonical public origin. CORS uses
	// it to identify same-origin requests without trusting the Host header.
	ExternalOrigin string
	// MCP is nil while the independently gated MCP surface is disabled.
	MCP http.Handler
}

PublicOptions carries transport facts that affect public response policy.

type ReadyChecker

type ReadyChecker interface {
	Ready(ctx context.Context) error
}

ReadyChecker reports whether a request would actually work.

type ReencryptService

type ReencryptService interface {
	ReencryptProject(ctx context.Context, actor service.Actor, orgID, projectID string) (service.ReencryptResult, error)
	ReencryptInstance(ctx context.Context, actor service.Actor) (service.ReencryptResult, error)
}

ReencryptService is the crypto reencrypt surface (#75/#187): move a scope's ciphertext onto the active DEK version and retire the old.

type RegistrationService

RegistrationService is the registration policy surface.

type RemoteService

type RemoteService interface {
	AddRemote(ctx context.Context, actor service.Actor, name, url, pin, credential string) (service.RemoteView, error)
	ListRemotes(ctx context.Context, actor service.Actor) ([]service.RemoteView, error)
	ShowRemote(ctx context.Context, actor service.Actor, name string) (service.RemoteView, error)
	RenameRemote(ctx context.Context, actor service.Actor, name, newName string) (service.RemoteView, error)
	RemoveRemote(ctx context.Context, actor service.Actor, name string) error
	RemoteOrigins(ctx context.Context, actor service.Actor) ([]string, error)
}

RemoteService is the viewing side's seam.

type RetentionSettingsService

type RetentionSettingsService interface {
	GetOrg(ctx context.Context, actor service.Actor, orgID domain.OrgID) (service.RetentionPolicy, error)
	SetOrg(ctx context.Context, actor service.Actor, orgID domain.OrgID, want service.RetentionPolicy) (service.RetentionPolicy, error)
	GetProject(ctx context.Context, actor service.Actor, scope domain.Scope) (service.ProjectRetention, error)
	SetProject(ctx context.Context, actor service.Actor, scope domain.Scope, want *service.RetentionPolicy) (service.ProjectRetention, error)
	GetHealth(ctx context.Context, actor service.Actor) (service.PruneHealth, error)
}

RetentionSettingsService is the org cap and project override surface.

type RevealService

type RevealService interface {
	Window(ctx context.Context, actor service.Actor, scope domain.Scope) (service.RevealWindow, error)
}

RevealService is the guard's read surface.

type RevisionService

type RevisionService interface {
	Diff(ctx context.Context, actor service.Actor, scope domain.Scope, leftRevision, rightRevision int64, keyID string) (service.RevisionDiff, error)
	PublishPlanned(ctx context.Context, actor service.Actor, scope domain.Scope, request service.PublishRequest) (service.PublishResult, error)
	Restore(ctx context.Context, actor service.Actor, scope domain.Scope, revision int64, keyName string) (service.RestoreResult, error)
	History(ctx context.Context, actor service.Actor, scope domain.Scope, beforeRevision int64, limit int) ([]service.RevisionView, error)
	Show(ctx context.Context, actor service.Actor, scope domain.Scope, revision int64) (service.RevisionDetail, error)
	Signals(ctx context.Context, actor service.Actor, scope domain.Scope) (service.EnvironmentSignals, error)
	PendingDrafts(ctx context.Context, actor service.Actor, scope domain.Scope) ([]service.PendingDraft, error)
	ExportWithParameters(ctx context.Context, actor service.Actor, scope domain.Scope, revision int64, reveal bool, supplied map[string]string) ([]service.ExportedValue, int64, error)
	Watch(ctx context.Context, actor service.Actor, scope domain.Scope) (<-chan service.AdvisoryEvent, error)
	RotateTokenKey(ctx context.Context, actor service.Actor) (service.TokenKeyRotation, error)
	RotateScanningKey(ctx context.Context, actor service.Actor) (service.ScanningKeyRotation, error)
}

RevisionService is the domain surface this transport exposes.

type RotationService

type RotationService interface {
	RotateDEK(ctx context.Context, actor service.Actor, scope service.DEKScope) (service.DEKRotation, error)
	RotateMasterKey(ctx context.Context, actor service.Actor) (service.MasterKeyRotation, error)
	RotateRootKey(ctx context.Context, actor service.Actor, phase service.RootKeyRotationPhase) (service.RootKeyRotation, error)
}

RotationService is the crypto key-hierarchy rotation surface (#75): the four operations that are not the token key. Like every service interface here the transport translates and decides nothing.

type RuleService

type RuleService interface {
	Replace(ctx context.Context, actor service.Actor, spec service.ReplaceRulesSpec) ([]service.RuleView, error)
	Create(ctx context.Context, actor service.Actor, spec service.RuleSpec) (service.RuleView, error)
	Revoke(ctx context.Context, actor service.Actor, org domain.OrgID, id string) error
	List(ctx context.Context, actor service.Actor, scope domain.Scope) ([]service.RuleView, error)
}

RuleService is the domain surface this transport exposes.

type RuntimeStatusSource

type RuntimeStatusSource interface {
	RuntimeStatus(context.Context) (service.RuntimeStatus, error)
}

type SAMLAuthService

type SAMLAuthService interface {
	SAMLStart(ctx context.Context, slug, purpose, environmentID, presented, proof string) (service.SAMLStartResult, error)
	SAMLACS(ctx context.Context, slug, encodedResponse, relayState, initiatorCookie string) (service.LoginResult, error)
	SAMLMetadata(ctx context.Context, slug string) ([]byte, error)
}

type SAMLProviderService

type SAMLProviderService interface {
	Put(ctx context.Context, actor service.Actor, slug string, in service.SAMLProviderInput) (service.SAMLProviderMutationResult, error)
	Patch(ctx context.Context, actor service.Actor, slug string, in service.SAMLProviderPatch) (service.SAMLProviderView, error)
	Get(ctx context.Context, actor service.Actor, slug string) (service.SAMLProviderView, error)
	List(ctx context.Context, actor service.Actor) ([]service.SAMLProviderView, error)
	Delete(ctx context.Context, actor service.Actor, slug string) error
	RefreshMetadata(ctx context.Context, actor service.Actor, slug string, in service.SAMLMetadataRefreshInput) (service.SAMLProviderMutationResult, error)
	ListSPKeys(ctx context.Context, actor service.Actor) ([]service.SAMLSPKeyView, error)
	RotateSPKey(ctx context.Context, actor service.Actor) (service.SAMLSPKeyView, error)
	RetireSPKey(ctx context.Context, actor service.Actor, fingerprint string) error
	CompromiseRetireSPKey(ctx context.Context, actor service.Actor, fingerprint string) (service.SAMLSPKeyView, error)
}

SAMLProviderService is the instance-scoped SAML provider administration surface, including the metadata diff-and-confirm ceremony.

type SCIMAdminService

type SCIMAdminService interface {
	CreateBinding(ctx context.Context, actor service.Actor, org domain.OrgID, in service.SCIMBindingInput) (service.SCIMBindingView, error)
	ListBindings(ctx context.Context, actor service.Actor, org domain.OrgID) ([]service.SCIMBindingView, error)
	GetBinding(ctx context.Context, actor service.Actor, org domain.OrgID, id string) (service.SCIMBindingView, error)
	DeleteBinding(ctx context.Context, actor service.Actor, org domain.OrgID, id string) error

	CreateMapping(ctx context.Context, actor service.Actor, org domain.OrgID, binding string, spec service.SCIMMappingSpec) (service.SCIMMappingResult, error)
	UpdateMapping(ctx context.Context, actor service.Actor, org domain.OrgID, binding string, spec service.SCIMMappingSpec) (service.SCIMMappingResult, error)
	DeleteMapping(ctx context.Context, actor service.Actor, org domain.OrgID, binding string, spec service.SCIMMappingSpec) (service.SCIMMappingResult, error)
	ListMappings(ctx context.Context, actor service.Actor, org domain.OrgID, binding string) ([]service.SCIMMappingView, error)

	MintCredential(ctx context.Context, actor service.Actor, org domain.OrgID, binding string, indefinite bool, proof string) (service.SCIMMintResult, error)
	ListCredentials(ctx context.Context, actor service.Actor, org domain.OrgID, binding string) ([]service.SCIMCredentialView, error)
	GetCredential(ctx context.Context, actor service.Actor, org domain.OrgID, binding, id string) (service.SCIMCredentialView, error)
	RevokeCredential(ctx context.Context, actor service.Actor, org domain.OrgID, binding, id string) error

	DirectoryUsers(ctx context.Context, actor service.Actor, org domain.OrgID, binding string) ([]service.SCIMDirectoryUser, error)
	DirectoryGroups(ctx context.Context, actor service.Actor, org domain.OrgID, binding string) ([]service.SCIMDirectoryGroup, error)
}

SCIMAdminService is the administration surface this transport needs.

type SCIMWireService

type SCIMWireService interface {
	CreateUser(ctx context.Context, actor service.Actor, org domain.OrgID, binding string, in service.DesiredUser) (service.SCIMUserResource, error)
	GetUser(ctx context.Context, actor service.Actor, org domain.OrgID, binding, id string) (service.SCIMUserResource, error)
	ListUsers(ctx context.Context, actor service.Actor, org domain.OrgID, binding string, filter scimproto.Filter, page scimproto.Page) ([]service.SCIMUserResource, int, error)
	ReplaceUser(ctx context.Context, actor service.Actor, org domain.OrgID, binding, id string, in service.DesiredUser) (service.SCIMUserResource, error)
	PatchUser(ctx context.Context, actor service.Actor, org domain.OrgID, binding, id string, commands []service.UserPatchCommand) (service.SCIMUserResource, error)
	DeleteUser(ctx context.Context, actor service.Actor, org domain.OrgID, binding, id string) error

	CreateGroup(ctx context.Context, actor service.Actor, org domain.OrgID, binding string, in service.DesiredGroup) (service.SCIMGroupResource, error)
	GetGroup(ctx context.Context, actor service.Actor, org domain.OrgID, binding, id string) (service.SCIMGroupResource, error)
	ListGroups(ctx context.Context, actor service.Actor, org domain.OrgID, binding string, filter scimproto.Filter, page scimproto.Page) ([]service.SCIMGroupResource, int, error)
	ReplaceGroup(ctx context.Context, actor service.Actor, org domain.OrgID, binding, id string, in service.DesiredGroup) (service.SCIMGroupResource, error)
	PatchGroup(ctx context.Context, actor service.Actor, org domain.OrgID, binding, id string, commands []service.GroupPatchCommand) (service.SCIMGroupResource, error)
	DeleteGroup(ctx context.Context, actor service.Actor, org domain.OrgID, binding, id string) error

	// Discovery authenticates a probe and returns the binding's DECLARED schema
	// extensions, so the two schema documents describe exactly what this
	// binding accepts and renders.
	Discovery(ctx context.Context, actor service.Actor, org domain.OrgID, binding string) ([]scimproto.ExtensionDecl, error)
	Authenticate(ctx context.Context, actor service.Actor, org domain.OrgID, binding string) error
	Unsupported(ctx context.Context, actor service.Actor, org domain.OrgID, binding, what string) error

	// PageBound is the server's `count` ceiling — an ops-spec bound the
	// transport must clamp against before it reaches the service.
	PageBound() int
}

SCIMWireService is the provisioning surface this transport needs.

type SSHSnapshotter

type SSHSnapshotter interface {
	SSHSnapshot() (activeCertificates, krlEntries int64, err error)
}

SSHSnapshotter is the SSH certificate gauge source, read at scrape time. An error (or a nil source) marks the gauges unknown for this scrape.

type SettingsService

type SettingsService interface {
	GetMachineReveal(ctx context.Context, actor service.Actor, scope domain.Scope) (service.MachineRevealSettings, error)
	SetMachineReveal(ctx context.Context, actor service.Actor, scope domain.Scope, enabled bool) (service.MachineRevealSettings, error)
	GetEnvironment(ctx context.Context, actor service.Actor, scope domain.Scope) (service.EnvironmentSettings, error)
	SetEnvironment(ctx context.Context, actor service.Actor, scope domain.Scope, want service.EnvironmentSettings) (service.EnvironmentSettings, error)
}

SettingsService is the `project-settings` surface.

type TLSMetrics

type TLSMetrics interface {
	TLSMetrics() (notAfterUnix int64, reloadFailures uint64)
}

TLSMetrics reports the label-free native TLS gauges served operationally.

type TransitSnapshotter

type TransitSnapshotter interface {
	TransitSnapshot() (live, rotationDue, pendingDeletion int64, err error)
}

TransitSnapshotter is the transit gauge source, read at scrape time. An error (or a nil source) marks the gauges unknown for this scrape.

type UpdateService

type UpdateService interface {
	GetStatus(ctx context.Context, actor service.Actor) (updatecheck.Status, error)
	Request(ctx context.Context, actor service.Actor, version string) (updater.Job, error)
	GetJob(ctx context.Context, actor service.Actor, id string) (updater.Job, error)
}

type ValueService

type ValueService interface {
	Get(ctx context.Context, actor service.Actor, scope domain.Scope, keyName string, reveal bool) (service.ValueCell, error)
	List(ctx context.Context, actor service.Actor, scope domain.Scope, reveal bool) ([]service.ValueCell, error)
	Set(ctx context.Context, actor service.Actor, scope domain.Scope, keyName, value string, acks []string) (service.StagedChange, error)
	Initialize(ctx context.Context, actor service.Actor, scope domain.Scope, keyName, value string, acks []string) (service.StagedChange, error)
	Unset(ctx context.Context, actor service.Actor, scope domain.Scope, keyName string) (service.StagedChange, error)
	Declare(ctx context.Context, actor service.Actor, scope domain.Scope, envIDs []string, keyName, value string) ([]service.ValueCell, []service.Finding, error)
	Copy(ctx context.Context, actor service.Actor, scope domain.Scope, req service.CopyRequest) (service.CopyResult, error)
	Diff(ctx context.Context, actor service.Actor, scope domain.Scope, left, right string, reveal bool) ([]service.DiffRow, error)
	Occurrences(ctx context.Context, actor service.Actor, scope domain.Scope, candidates []service.ImportCandidate) (service.ImportPresence, error)
	Import(ctx context.Context, actor service.Actor, scope domain.Scope, req service.ImportRequest) (service.ImportResult, error)
}

ValueService is the domain surface this transport exposes.

type WireError

type WireError struct {
	// contains filtered or unexported fields
}

WireError is the closed server-layer policy for one public error class. Its fields stay private so handlers cannot assemble status, code, message, and detail handling independently.

type WorkspaceService

type WorkspaceService interface {
	Serve(ctx context.Context, actor service.Actor) (remotefetch.Listing, error)
	MintConnection(ctx context.Context, actor service.Actor, label string, req service.MintRequest) (service.MintConnectionResult, error)
	ListConnections(ctx context.Context, actor service.Actor) ([]service.ConnectionView, error)
	ShowConnection(ctx context.Context, actor service.Actor, id string) (service.ConnectionView, error)
	RevokeConnection(ctx context.Context, actor service.Actor, id string) error
	ListOrigins(ctx context.Context, actor service.Actor) ([]service.OriginView, error)
	AddOrigin(ctx context.Context, actor service.Actor, origin string) (service.OriginView, error)
	RemoveOrigin(ctx context.Context, actor service.Actor, origin string) (int64, error)
	OriginAllowed(ctx context.Context, origin string) (bool, error)
	StartHandoff(ctx context.Context, req service.HandoffRequest) (service.HandoffStart, error)
	ShowHandoff(ctx context.Context, actor service.Actor, state string) (service.HandoffView, error)
	ApproveHandoff(ctx context.Context, actor service.Actor, state string) (string, string, error)
	RedeemHandoff(ctx context.Context, code, pkceVerifier, origin string) (service.WorkspaceSession, error)
	ListSessions(ctx context.Context, actor service.Actor) ([]service.SessionView, error)
	RevokeSession(ctx context.Context, actor service.Actor, id string) error
}

WorkspaceService is the serving side's seam.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL