Documentation
¶
Overview ¶
Package adminapi implements the tenant-scoped MCP Admin API domain services (inventory, decision query/explanation, policy validate/simulate/compare, local policy publication, approvals, health and configuration) that PR-9 exposes through the existing Culvert admin HTTP surface and the read-only Management MCP tool catalog.
The domain services here are transport-agnostic and RBAC-independent: HTTP handlers in package main and the Management MCP dispatcher both call the same services, and each enforces its own authorization before doing so. Nothing in this package performs upstream execution, materializes a credential, contacts a credential provider, or publishes a signed CP→DP snapshot — an ALLOW-class decision still returns execution_state=not_implemented, and local policy publication is reported as distribution_state=local_only until PR-10.
Index ¶
- type ApprovalCounts
- type ApprovalView
- type CapabilityHealth
- type CatalogSource
- type CompareResult
- type Config
- type ConfigStore
- type DecisionFilter
- type DecisionService
- type DecisionView
- type DurabilityHealth
- type EventReader
- type ExplanationView
- type GatewayConfig
- type HealthService
- type HealthSources
- type HealthView
- type InventoryCounts
- type InventoryService
- func (s *InventoryService) GetServer(tenant, serverID string) (ServerView, error)
- func (s *InventoryService) GetTool(tenant, serverID, name string) (ToolView, error)
- func (s *InventoryService) ListServers(tenant string, limit int) ([]ServerView, error)
- func (s *InventoryService) ListTools(tenant, serverID string, limit int) ([]ToolView, error)
- type Limits
- func (l Limits) ApprovalTTL() time.Duration
- func (l Limits) MaxApprovalsPerTenant() int
- func (l Limits) MaxCandidateBytes() int
- func (l Limits) MaxCompareSamples() int
- func (l Limits) MaxConcurrentSims() int
- func (l Limits) MaxExplainEntries() int
- func (l Limits) MaxFilters() int
- func (l Limits) MaxGUIRows() int
- func (l Limits) MaxHealthBytes() int
- func (l Limits) MaxInventoryResults() int
- func (l Limits) MaxMgmtInputBytes() int
- func (l Limits) MaxMgmtOutputBytes() int
- func (l Limits) MaxMgmtTools() int
- func (l Limits) MaxPageSize() int
- func (l Limits) MaxPendingApprovals() int
- func (l Limits) MaxProjectionScan() int
- func (l Limits) MaxPublicationReqs() int
- func (l Limits) MaxQueryRange() time.Duration
- func (l Limits) MaxRequestBytes() int
- func (l Limits) MaxSimCorpus() int
- func (l Limits) MaxSpoolScanBytes() int
- func (l Limits) MinConfigUpdateGap() time.Duration
- type ListenerConfig
- type MCPConfig
- type ManagementAccessHealth
- type ManagementBackend
- type ManagementConfig
- type Params
- type PolicyService
- func (s *PolicyService) Compare(capability string, raw []byte, cases []simulate.Case) (CompareResult, error)
- func (s *PolicyService) Simulate(capability string, raw []byte, cases []simulate.Case) (SimResult, error)
- func (s *PolicyService) Stores() PolicyStores
- func (s *PolicyService) Validate(capability string, raw []byte) ValidateResult
- type PolicyStores
- type PublicationCommitter
- type PublicationService
- func (s *PublicationService) Approve(id approval.ID, approver approval.PrincipalID, appCommit approval.Committer) (approval.Receipt, error)
- func (s *PublicationService) Create(capability, tenant string, requester approval.PrincipalID, raw []byte, ...) (approval.ID, error)
- func (s *PublicationService) Publish(id approval.ID, tenant string, rc approval.Receipt) (PublishResult, error)
- func (s *PublicationService) Reject(id approval.ID, approver approval.PrincipalID, reason string, ...) error
- type PublishResult
- type RegistrySource
- type RuntimeStateHealth
- type SearchResult
- type ServerView
- type Service
- type SimCaseResult
- type SimResult
- type ToolView
- type ValidateResult
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type ApprovalCounts ¶
ApprovalCounts exposes bounded pending-projection counts per capability.
type ApprovalView ¶
type ApprovalView struct {
ID string `json:"id"`
Kind string `json:"kind"`
State string `json:"state"`
Tenant string `json:"tenant"`
Capability string `json:"capability"`
Requester string `json:"requester"`
Approver string `json:"approver,omitempty"`
Action string `json:"action,omitempty"`
Resource string `json:"resource,omitempty"`
ServerID string `json:"server_id,omitempty"`
ToolFingerprint string `json:"tool_fingerprint,omitempty"`
OperationClass string `json:"operation_class,omitempty"`
RiskClass string `json:"risk_class,omitempty"`
CredentialProfileRef string `json:"credential_profile_ref,omitempty"`
PowerCeiling string `json:"power_ceiling,omitempty"`
DecisionEventID string `json:"decision_event_id,omitempty"`
CandidateHash string `json:"candidate_hash,omitempty"`
BaseRevision uint64 `json:"base_revision,omitempty"`
ProposedRevision uint64 `json:"proposed_revision,omitempty"`
PolicyRevision uint64 `json:"policy_revision,omitempty"`
CatalogRevision uint64 `json:"catalog_revision,omitempty"`
CreatedUnixNano int64 `json:"created_unix_nano"`
ExpiryUnixNano int64 `json:"expiry_unix_nano"`
Reason string `json:"reason,omitempty"`
}
ApprovalView is the safe, complete view of one approval or publication request. It carries the exact fields the MCP-POLICY-007 approval dialog must display — action, resource, server/tool, requester/agent/client, reason and rule, credential profile and power ceiling, policy/catalog revisions, durable event id, age and expiry — with NO credential material and NO raw body. The decisive condition and inspection state are cross-referenced by the dialog via the bound decision event (DecisionEventID -> decision explanation).
func ApprovalViewOf ¶
func ApprovalViewOf(r *approval.Request) ApprovalView
ApprovalViewOf is the exported mapping used by the admin HTTP layer.
type CapabilityHealth ¶
type CapabilityHealth struct {
Capability string `json:"capability"`
Runtime RuntimeStateHealth `json:"runtime"`
Durability DurabilityHealth `json:"durability"`
Servers int `json:"servers"`
QuarantinedTools int `json:"quarantined_tools"`
DriftedTools int `json:"drifted_tools"`
PolicyRevision uint64 `json:"policy_revision"`
PolicySnapshotHash string `json:"policy_snapshot_hash"`
PendingApprovals int `json:"pending_approvals"`
PendingPublications int `json:"pending_publications"`
}
CapabilityHealth is the composed safe health of one MCP capability.
type CatalogSource ¶
type CatalogSource interface {
Tools() []catalog.ToolRecord
CatalogRevision() uint64
}
CatalogSource exposes the current tool records and catalog revision.
type CompareResult ¶
type CompareResult struct {
Capability string `json:"capability"`
CandidateHash string `json:"candidate_hash"`
BaseRevision uint64 `json:"base_revision"`
NewAllow int `json:"new_allow"`
NewDeny int `json:"new_deny"`
NewQuarantine int `json:"new_quarantine"`
NewApprovalRequired int `json:"new_approval_required"`
AffectedRules []string `json:"affected_rules"`
SampleCaseIDs []string `json:"sample_case_ids"`
}
CompareResult is the safe blast-radius summary of active-vs-candidate.
type Config ¶
type Config struct {
MaxRequestBytes int
MaxCandidateBytes int
MaxPageSize int
MaxQueryRange time.Duration
MaxFilters int
MaxExplainEntries int
MaxConcurrentSims int
MaxSimCorpus int
MaxCompareSamples int
MaxPendingApprovals int
MaxApprovalsPerTenant int
ApprovalTTL time.Duration
MaxPublicationReqs int
MaxMgmtTools int
MaxMgmtInputBytes int
MaxMgmtOutputBytes int
MaxInventoryResults int
MaxHealthBytes int
MaxGUIRows int
MinConfigUpdateGap time.Duration
MaxProjectionScan int
MaxSpoolScanBytes int
}
Config is the mutable input to NewLimits. A zero Config is invalid; every field must be set. Durations are validated for finiteness and range. Nothing here is a secret or a runtime-mutable singleton.
type ConfigStore ¶
type ConfigStore struct {
// contains filtered or unexported fields
}
ConfigStore holds the current MCP configuration behind an RWMutex. Reads are lock-free-ish (RLock); a Set validates the candidate and replaces atomically, retaining the previous configuration on any validation failure.
func NewConfigStore ¶
func NewConfigStore(maxOutputBytes int) *ConfigStore
NewConfigStore returns a store seeded with the safe defaults.
func (*ConfigStore) Current ¶
func (s *ConfigStore) Current() MCPConfig
Current returns a copy of the active configuration.
func (*ConfigStore) Set ¶
func (s *ConfigStore) Set(cand MCPConfig) error
Set validates cand and, only if valid, replaces the active configuration. On any validation failure the previous configuration is retained unchanged.
type DecisionFilter ¶
type DecisionFilter struct {
Action string
ReasonCode string
RuleID string
ServerID string
ToolName string
ToolFingerprint string
PrincipalID string
AgentID string
ClientID string
ExecutionState string
PolicySnapshotHash string
CredentialProfileRef string
StartUnixNano int64
EndUnixNano int64
}
DecisionFilter carries the safe, bounded query filters. A zero field is "any". Every string field is matched by EXACT equality against the persisted event (never substring/regex), so no filter can scan into secret or raw-content fields; the searchable surface is exactly the fields projected into DecisionView/ExplanationView.
type DecisionService ¶
type DecisionService struct {
// contains filtered or unexported fields
}
DecisionService answers bounded, tenant-scoped decision search and historical explanation over PR-8 committed events. It never re-evaluates policy.
func NewDecisionService ¶
func NewDecisionService(reader EventReader, lim Limits) *DecisionService
NewDecisionService builds a decision query service.
func (*DecisionService) Explain ¶
func (s *DecisionService) Explain(capability, tenant, eventID string) (ExplanationView, error)
Explain returns the full historical explanation of one committed decision, projected from the persisted event. Uniform not-found across tenants.
func (*DecisionService) Search ¶
func (s *DecisionService) Search(capability, tenant, cursor string, limit int, f DecisionFilter) (SearchResult, error)
Search returns a bounded, deterministic, tenant-scoped page of decisions. Events for other tenants are skipped uniformly (no count or existence leak).
type DecisionView ¶
type DecisionView struct {
EventID string `json:"event_id"`
Sequence uint64 `json:"sequence"`
Partition string `json:"partition"`
Capability string `json:"capability"`
TimeUnixNano int64 `json:"time_unix_nano"`
Tenant string `json:"tenant"`
PrincipalID string `json:"principal_id"`
PrincipalType string `json:"principal_type"`
AgentID string `json:"agent_id,omitempty"`
ServerID string `json:"server_id,omitempty"`
ToolName string `json:"tool_name,omitempty"`
Action string `json:"action"`
ReasonCode string `json:"reason_code"`
MatchedRuleID string `json:"matched_rule_id,omitempty"`
OperationClass string `json:"operation_class,omitempty"`
ExecutionState string `json:"execution_state,omitempty"`
}
DecisionView is a safe, bounded search-result summary of one committed event.
type DurabilityHealth ¶
type DurabilityHealth struct {
CriticalState string `json:"critical_state"`
DenialState string `json:"denial_state"`
Severity string `json:"severity"`
CritBytes int64 `json:"crit_bytes"`
CritQuota int64 `json:"crit_quota"`
OrdBytes int64 `json:"ord_bytes"`
OrdQuota int64 `json:"ord_quota"`
DenBytes int64 `json:"den_bytes"`
DenQuota int64 `json:"den_quota"`
CriticalReserveFree int64 `json:"critical_reserve_free"`
CommitFailures uint64 `json:"commit_failures"`
SyncFailures uint64 `json:"sync_failures"`
EncryptionFailures uint64 `json:"encryption_failures"`
DenialLoss uint64 `json:"denial_loss"`
CriticalDegradations uint64 `json:"critical_degradations"`
RecoveryState string `json:"recovery_state"`
ExporterLag uint64 `json:"exporter_lag"`
}
DurabilityHealth is the safe per-capability PR-8 durability snapshot. It carries only bounded numeric/state fields — no tenant, subject, session, tool argument, URL or secret.
type EventReader ¶
type EventReader interface {
CommittedEvents(capability, partition string, afterSeq uint64, max int) (events []evmodel.Event, seqs []uint64, next uint64, err error)
}
EventReader is the narrow, bounded read seam over PR-8 committed events. package main adapts events.Manager / spool.CommittedForExport; tests fake it. It returns only committed, safe, typed event projections — never a raw spool record or encrypted segment.
type ExplanationView ¶
type ExplanationView struct {
EventID string `json:"event_id"`
CorrelationID string `json:"correlation_id"`
ReplayID string `json:"replay_id"`
Capability string `json:"capability"`
Partition string `json:"partition"`
TimeUnixNano int64 `json:"time_unix_nano"`
Tenant string `json:"tenant"`
PrincipalID string `json:"principal_id"`
PrincipalType string `json:"principal_type"`
AgentID string `json:"agent_id,omitempty"`
ClientID string `json:"client_id,omitempty"`
ServerID string `json:"server_id,omitempty"`
ToolName string `json:"tool_name,omitempty"`
ToolFingerprint string `json:"tool_fingerprint,omitempty"`
ResourceRef string `json:"resource_ref,omitempty"`
ResourceHash string `json:"resource_hash,omitempty"`
Assurance string `json:"assurance,omitempty"`
Action string `json:"action"`
ReasonCode string `json:"reason_code"`
MatchedRuleID string `json:"matched_rule_id,omitempty"`
DecisiveConditionID string `json:"decisive_condition_id,omitempty"`
Remediation string `json:"remediation,omitempty"`
OperationClass string `json:"operation_class,omitempty"`
RiskClass string `json:"risk_class,omitempty"`
ExecutionState string `json:"execution_state,omitempty"`
Obligations []string `json:"obligations,omitempty"`
PolicyRevision uint64 `json:"policy_revision"`
CatalogRevision uint64 `json:"catalog_revision"`
RegistryRevision uint64 `json:"registry_revision,omitempty"`
InspectionRevision uint64 `json:"inspection_revision,omitempty"`
RuntimeRevision uint64 `json:"runtime_revision,omitempty"`
PolicySnapshotHash string `json:"policy_snapshot_hash,omitempty"`
InspectionSchemaStatus string `json:"inspection_schema_status,omitempty"`
FindingClasses []string `json:"finding_classes,omitempty"`
MaxSeverity string `json:"max_severity,omitempty"`
DLPDisposition string `json:"dlp_disposition,omitempty"`
DestinationClass string `json:"destination_class,omitempty"`
CredentialProfileRef string `json:"credential_profile_ref,omitempty"`
CredentialPower string `json:"credential_power_ceiling,omitempty"`
// Source marks the explanation as historical (never a live re-evaluation).
Source string `json:"source"`
}
ExplanationView is the full, safe historical explanation of ONE committed decision — projected exclusively from the persisted event, never re-evaluated against the current policy. It contains no raw arguments, output, secret, PII, token, credential material, sensitive query or provider error.
type GatewayConfig ¶
type GatewayConfig struct {
ListenerConfig
UnknownToolDefaultAction string `json:"unknown_tool_default_action"` // "deny" | "quarantine"
PolicyDefaultAction string `json:"policy_default_action"` // "deny" (default-deny)
RateLimitRPS int `json:"rate_limit_rps"`
RateLimitBurst int `json:"rate_limit_burst"`
}
GatewayConfig is the Gateway-capability listener/access configuration.
type HealthService ¶
type HealthService struct {
// contains filtered or unexported fields
}
HealthService composes the safe MCP health snapshot.
func NewHealthService ¶
func NewHealthService(src HealthSources, lim Limits) *HealthService
NewHealthService builds a health aggregator.
func (*HealthService) Snapshot ¶
func (s *HealthService) Snapshot() HealthView
Snapshot composes the current safe health view. Each capability is built from its own sources; the two are never mixed.
type HealthSources ¶
type HealthSources struct {
Durability func(capability string) DurabilityHealth
Runtime func(capability string) RuntimeStateHealth
Policy PolicyStores
Approvals ApprovalCounts
Inventory InventoryCounts
Config *ConfigStore
}
HealthSources are the narrow, capability-keyed inputs the aggregator composes. Durability and Runtime are funcs so each capability is fetched independently (isolation) and tests can inject per-capability behavior.
type HealthView ¶
type HealthView struct {
Gateway CapabilityHealth `json:"gateway"`
Management CapabilityHealth `json:"management"`
DistributionState string `json:"distribution_state"` // always local_only in PR-9
ManagementAccess ManagementAccessHealth `json:"management_access"`
}
HealthView is the complete safe MCP health snapshot. Gateway and Management are composed from SEPARATE sources so a degradation in one is never written into the other (capability isolation).
type InventoryCounts ¶
InventoryCounts exposes bounded per-capability inventory counts.
type InventoryService ¶
type InventoryService struct {
// contains filtered or unexported fields
}
InventoryService produces tenant-scoped, redacted, bounded inventory views.
func NewInventoryService ¶
func NewInventoryService(reg RegistrySource, cat CatalogSource, lim Limits) *InventoryService
NewInventoryService builds an inventory service.
func (*InventoryService) GetServer ¶
func (s *InventoryService) GetServer(tenant, serverID string) (ServerView, error)
GetServer returns a single server within the caller's tenant, or a uniform not-found (no cross-tenant existence leak).
func (*InventoryService) GetTool ¶
func (s *InventoryService) GetTool(tenant, serverID, name string) (ToolView, error)
GetTool returns one tool within the caller's tenant, or uniform not-found.
func (*InventoryService) ListServers ¶
func (s *InventoryService) ListServers(tenant string, limit int) ([]ServerView, error)
ListServers returns a bounded, tenant-scoped, redacted server list ordered by ServerID. A caller only ever sees servers within its own tenant (OwnerScope).
func (*InventoryService) ListTools ¶
func (s *InventoryService) ListTools(tenant, serverID string, limit int) ([]ToolView, error)
ListTools returns a bounded, tenant-scoped, redacted tool list. Tools are joined to their server's tenant; an unknown/quarantined tool remains visibly quarantined (never presented as usable).
type Limits ¶
type Limits struct {
// contains filtered or unexported fields
}
Limits is an immutable, validated admin bound set. It mirrors the limits.Limits / EventLimits pattern: an unexported Config read only through accessors, a single Validate gate, hard-cap ceilings, and no mutable state.
func DefaultLimits ¶
func DefaultLimits() Limits
DefaultLimits returns the conservative safe-default admin bound set.
func (Limits) ApprovalTTL ¶
ApprovalTTL is the bounded lifetime of an approval/publication request.
func (Limits) MaxApprovalsPerTenant ¶
MaxApprovalsPerTenant bounds pending approvals attributable to one tenant.
func (Limits) MaxCandidateBytes ¶
MaxCandidateBytes bounds one candidate policy document.
func (Limits) MaxCompareSamples ¶
MaxCompareSamples bounds changed-case samples in a comparison.
func (Limits) MaxConcurrentSims ¶
MaxConcurrentSims bounds concurrent simulations.
func (Limits) MaxExplainEntries ¶
MaxExplainEntries bounds evidence/trace entries in one explanation.
func (Limits) MaxFilters ¶
MaxFilters bounds active filters on one query.
func (Limits) MaxGUIRows ¶
MaxGUIRows bounds rows a GUI view may request at once.
func (Limits) MaxHealthBytes ¶
MaxHealthBytes bounds one health snapshot.
func (Limits) MaxInventoryResults ¶
MaxInventoryResults bounds inventory records returned in one page set.
func (Limits) MaxMgmtInputBytes ¶
MaxMgmtInputBytes bounds one Management tool input.
func (Limits) MaxMgmtOutputBytes ¶
MaxMgmtOutputBytes bounds one Management tool result (MCP-MGMT-004).
func (Limits) MaxMgmtTools ¶
MaxMgmtTools bounds the Management tool catalog size.
func (Limits) MaxPendingApprovals ¶
MaxPendingApprovals bounds pending approvals held in the projection.
func (Limits) MaxProjectionScan ¶
MaxProjectionScan bounds records a projection rebuild may scan.
func (Limits) MaxPublicationReqs ¶
MaxPublicationReqs bounds pending publication requests.
func (Limits) MaxQueryRange ¶
MaxQueryRange bounds a query time range.
func (Limits) MaxRequestBytes ¶
MaxRequestBytes bounds one admin request body.
func (Limits) MaxSimCorpus ¶
MaxSimCorpus bounds cases in one simulation corpus.
func (Limits) MaxSpoolScanBytes ¶
MaxSpoolScanBytes bounds bytes a bounded decision-query scan may read.
func (Limits) MinConfigUpdateGap ¶
MinConfigUpdateGap is the minimum spacing between config updates.
type ListenerConfig ¶
type ListenerConfig struct {
Enabled bool `json:"enabled"`
BindAddress string `json:"bind_address"`
Port int `json:"port"`
ProtocolVersion string `json:"protocol_version_policy"`
OriginHostAllowlist []string `json:"origin_host_allowlist"`
// TLSProfileRef is a reference to a configured TLS profile, not key material.
TLSProfileRef string `json:"tls_profile_ref"`
ClientCertMode string `json:"client_cert_mode"` // "none" | "request" | "require"
}
ListenerConfig is the PR-9-owned, node-local (RC-6) configuration for one MCP capability listener plus its access controls. It carries references and metadata only — never a private key, bearer token, client secret or raw credential. Distribution to other nodes is NOT implemented here (PR-10); a config read reports distribution_state=local_only.
type MCPConfig ¶
type MCPConfig struct {
Gateway GatewayConfig `json:"gateway"`
Management ManagementConfig `json:"management"`
}
MCPConfig is the complete PR-9 MCP configuration: separate Gateway and Management settings whose runtime state is NOT shared (capability isolation).
func DefaultMCPConfig ¶
func DefaultMCPConfig() MCPConfig
DefaultMCPConfig returns the safe-default configuration: both capabilities disabled, no wildcard bind, TLS required, distinct ports, Management read-only and defaulting to at least viewer, with a bounded/redacted Management output.
type ManagementAccessHealth ¶
type ManagementAccessHealth struct {
Enabled bool `json:"enabled"`
EndpointBound bool `json:"endpoint_bound"`
DefaultMinRole string `json:"default_min_role"`
OutputMaxBytes int `json:"output_max_bytes"`
MutationEnabled bool `json:"mutation_enabled"`
}
ManagementAccessHealth is the safe Management-access surface state.
type ManagementBackend ¶
type ManagementBackend struct {
// contains filtered or unexported fields
}
ManagementBackend implements management.Backend over the adminapi Service. It is READ-ONLY plus draft/validate/simulate: every branch calls a read or a stateless policy evaluation and returns safe DTO bytes scoped to id.Tenant. There is no branch that publishes, approves, mutates config or materializes a credential — those tools are not in the catalog and cannot reach here.
func NewManagementBackend ¶
func NewManagementBackend(svc *Service) *ManagementBackend
NewManagementBackend adapts a Service as a management.Backend.
func (*ManagementBackend) Invoke ¶
func (b *ManagementBackend) Invoke(tool string, id management.Identity, input []byte) ([]byte, error)
Invoke dispatches a fixed-catalog tool by name. Tenant scope comes from the resolved Management identity, never from tool arguments.
type ManagementConfig ¶
type ManagementConfig struct {
ListenerConfig
AuthMode string `json:"auth_mode"` // "oauth-token"
DefaultMinRole string `json:"default_min_role"` // "viewer" | "operator" | "admin" (>= viewer)
MutationEnabled bool `json:"mutation_enabled"` // MUST be false in V1
TenantScopeMode string `json:"tenant_scope_mode"` // "strict" | "explicit-global"
OutputMaxBytes int `json:"output_max_bytes"` // MCP-MGMT-004 bound
OutputRedaction string `json:"output_redaction_profile"`
RateLimitRPS int `json:"rate_limit_rps"`
RateLimitBurst int `json:"rate_limit_burst"`
}
ManagementConfig is the Management-capability listener/access configuration. Management runs CP-side only; its config is never DP-synced. In V1 mutation is unavailable: MutationEnabled MUST remain false (MCP-MGMT-001 / ADR-0024 D-13).
type Params ¶
type Params struct {
Registry RegistrySource
Catalog CatalogSource
Events EventReader
PolicyStores PolicyStores
PolicyLimits policy.Limits
Approvals *approval.Store
PubCommitter PublicationCommitter
IDGen func() approval.ID
Health HealthSources
ConfigStore *ConfigStore
Limits Limits
Clock func() time.Time
}
Params bundles the dependencies needed to build a Service.
type PolicyService ¶
type PolicyService struct {
// contains filtered or unexported fields
}
PolicyService implements validate / simulate / compare over the SAME PR-6 engine the runtime uses (via policy.Compile + policy/simulate). It never publishes or mutates a store — those are the publication workflow's job.
func NewPolicyService ¶
func NewPolicyService(stores PolicyStores, plim policy.Limits, lim Limits, clock func() time.Time) *PolicyService
NewPolicyService builds a PolicyService. plim is the policy engine limit set (shared with the runtime); lim bounds candidate/corpus/sample sizes.
func (*PolicyService) Compare ¶
func (s *PolicyService) Compare(capability string, raw []byte, cases []simulate.Case) (CompareResult, error)
Compare compiles the candidate and compares active-vs-candidate over the corpus, returning a bounded blast-radius summary. It publishes nothing.
func (*PolicyService) Simulate ¶
func (s *PolicyService) Simulate(capability string, raw []byte, cases []simulate.Case) (SimResult, error)
Simulate compiles the candidate and runs the bounded corpus through the shared evaluator. It publishes nothing.
func (*PolicyService) Stores ¶
func (s *PolicyService) Stores() PolicyStores
Stores returns the policy-store resolver (used by the admin HTTP layer to read the current active policy per capability).
func (*PolicyService) Validate ¶
func (s *PolicyService) Validate(capability string, raw []byte) ValidateResult
Validate compiles the candidate and returns its safe metadata.
type PolicyStores ¶
PolicyStores resolves the capability-local PR-6 policy store. package main supplies the real stores; tests supply fakes.
type PublicationCommitter ¶
type PublicationCommitter interface {
CommitPublication(capability, tenant, candidateHash string, base, proposed uint64) (evidenceDigest string, err error)
}
PublicationCommitter durably records the PR-8 P-CRIT configuration-publication decision event and returns safe evidence, or a classified error on which the publication fails closed (nothing is published, the active policy is retained). package main backs this with events.Manager.CommitDecision; tests fake it.
type PublicationService ¶
type PublicationService struct {
// contains filtered or unexported fields
}
PublicationService owns the local policy-publication workflow: create (compile + bind an approval), approve/reject (four-eyes via the approval store), and publish (commit the P-CRIT event, THEN publish into the local PR-6 store).
func NewPublicationService ¶
func NewPublicationService(ps *PolicyService, stores PolicyStores, approvals *approval.Store, commit PublicationCommitter, idgen func() approval.ID, clock func() time.Time) *PublicationService
NewPublicationService builds the workflow. idgen must return unpredictable, unique IDs (package main uses crypto/rand).
func (*PublicationService) Approve ¶
func (s *PublicationService) Approve(id approval.ID, approver approval.PrincipalID, appCommit approval.Committer) (approval.Receipt, error)
Approve grants a pending publication request (four-eyes). The live base revision is resolved from the capability store at decide time (TOCTOU guard).
func (*PublicationService) Create ¶
func (s *PublicationService) Create(capability, tenant string, requester approval.PrincipalID, raw []byte, expectedBase uint64) (approval.ID, error)
Create compiles+validates the candidate, checks the expected base revision, and records a pending four-eyes publication request. It publishes nothing.
Management MCP is non-mutating in V1: a Management policy publication is a mutating workflow and is rejected here fail-closed (defense-in-depth; the admin UI never offers the control, and the handler rejects it too). This guard blocks a Management policy-publication workflow; it does not introduce one.
func (*PublicationService) Publish ¶
func (s *PublicationService) Publish(id approval.ID, tenant string, rc approval.Receipt) (PublishResult, error)
Publish performs the final local publication: it verifies the approval is granted and the receipt is bound to this exact candidate, commits the P-CRIT configuration-publication event, and ONLY on a confirmed receipt publishes into the local PR-6 store. Any failure publishes nothing and retains the active policy.
type PublishResult ¶
type PublishResult struct {
Capability string `json:"capability"`
Revision uint64 `json:"revision"`
CandidateHash string `json:"candidate_hash"`
DistributionState string `json:"distribution_state"`
EvidenceDigest string `json:"evidence_digest"`
}
PublishResult is the safe outcome of a local publication. DistributionState is always local_only in PR-9 — signed CP→DP distribution is PR-10.
type RegistrySource ¶
type RegistrySource interface {
Servers() []registry.ServerRecord
RegistryRevision() uint64
}
RegistrySource and CatalogSource are the narrow read seams the inventory service consumes. package main adapts *registry.Registry / *catalog.Catalog; tests supply fakes. They return the concrete upstream records; the inventory service maps them to SAFE, redacted view DTOs.
type RuntimeStateHealth ¶
type RuntimeStateHealth struct {
State string `json:"state"` // disabled|invalid|configured_not_started|starting|ready|degraded|draining|stopped
ListenerReady bool `json:"listener_ready"`
Draining bool `json:"draining"`
ActiveSessions int `json:"active_sessions"`
AcceptedConns uint64 `json:"accepted_conns"`
RejectedConns uint64 `json:"rejected_conns"`
InFlight int `json:"in_flight"`
// EnableRequested reports whether the operator explicitly asked to activate this
// capability's listener (QUAL-1). It distinguishes "disabled by default" (false)
// from "enable requested but configuration invalid" (true with State=="invalid").
EnableRequested bool `json:"enable_requested"`
// Reason is a bounded, secret-free classification when State is "invalid" (e.g.
// "tls_material_unavailable", "no_trusted_keys"); never a raw error or path.
Reason string `json:"reason,omitempty"`
// Posture is "observe" when the listener is active in the QUAL-1 Observe posture.
Posture string `json:"posture,omitempty"`
// ExecutionEnabled reports whether upstream tool execution is composed. QUAL-1
// ships NO executor, so a bound Gateway observe listener always reports false.
ExecutionEnabled bool `json:"execution_enabled"`
}
RuntimeStateHealth is the safe per-capability listener/runtime snapshot.
type SearchResult ¶
type SearchResult struct {
Decisions []DecisionView `json:"decisions"`
NextCursor string `json:"next_cursor,omitempty"`
}
SearchResult is a bounded page of decisions plus the next opaque cursor (empty when the stream is exhausted).
type ServerView ¶
type ServerView struct {
ServerID string `json:"server_id"`
Tenant string `json:"tenant"`
Capability string `json:"capability"`
Enabled bool `json:"enabled"`
Verification string `json:"verification"` // "verified" | "identity_mismatch"
IdentityChanged bool `json:"identity_changed"`
Revision uint64 `json:"revision"`
CredentialProfileRef string `json:"credential_profile_ref,omitempty"`
EndpointConfigured bool `json:"endpoint_configured"`
}
ServerView is a safe, redacted inventory view of one registered server. It never exposes the raw endpoint, pinned identity material, or credential material — only opaque IDs, safe references and lifecycle state.
type Service ¶
type Service struct {
Inventory *InventoryService
Decisions *DecisionService
Policy *PolicyService
Publication *PublicationService
Health *HealthService
Config *ConfigStore
Approvals *approval.Store
Limits Limits
}
Service is the adminapi composition root: it ties the individual domain services together behind one struct that both the admin HTTP handlers (package main) and the Management MCP backend consume. It holds no HTTP, session or RBAC concern — callers authorize before invoking it.
func NewService ¶
NewService builds the composition root from its dependencies. Any source may be nil for a capability that is not wired; the corresponding service then returns empty/disabled results rather than panicking.
type SimCaseResult ¶
type SimCaseResult struct {
ID string `json:"id"`
Action string `json:"action"`
Reason string `json:"reason"`
MatchedRule string `json:"matched_rule"`
}
SimCaseResult is one simulated case's safe outcome.
type SimResult ¶
type SimResult struct {
Capability string `json:"capability"`
CandidateHash string `json:"candidate_hash"`
Cases []SimCaseResult `json:"cases"`
}
SimResult is the safe result of simulating a candidate against a corpus.
type ToolView ¶
type ToolView struct {
ServerID string `json:"server_id"`
Name string `json:"name"`
Fingerprint string `json:"fingerprint"`
Disposition string `json:"disposition"` // usable | quarantined | review_required | ...
Quarantined bool `json:"quarantined"`
ReviewRequired bool `json:"review_required"`
DestinationClass string `json:"destination_class"`
Revision uint64 `json:"revision"`
}
ToolView is a safe, redacted inventory view of one catalog tool. It never exposes complete schemas, arguments or output — only the fingerprint digest, disposition and destination class.
type ValidateResult ¶
type ValidateResult struct {
OK bool `json:"ok"`
Capability string `json:"capability"`
CandidateHash string `json:"candidate_hash"`
RuleCount int `json:"rule_count"`
DefaultAction string `json:"default_action"`
SchemaVersion int `json:"schema_version"`
Reason string `json:"reason,omitempty"` // classified reason code on failure
}
ValidateResult is the safe result of compiling/validating a candidate policy.