Documentation
¶
Overview ¶
Package core is L1 of the SigComply CLI: the frozen Go interfaces and structs that every higher layer depends on. Framework, Policy, EvidenceRecord, Envelope, Vault, Rule, SourcePlugin, CloudClient, SubmissionPayload, and their supporting value types live here.
Once published these types are stable. The aggregation boundary (SubmissionPayload) is structurally counts-only and must not gain fields that could carry resource identifiers across L6.
See docs/architecture/02-layers.md for the full layer contract.
Index ¶
- type AggregatedPolicy
- type AppliedException
- type CIEnvironment
- type CloudClient
- type Control
- type Envelope
- type EnvelopeSignature
- type EvidenceRecord
- type EvidenceType
- type Framework
- type Manifest
- type ManifestSignature
- type ParameterSpec
- type Policy
- type PolicyRef
- type PolicyResult
- type PolicyStatus
- type Repository
- type Rule
- type RuleInput
- type RuleResult
- type RunSummary
- type Severity
- type Slot
- type SlotCardinality
- type SlotRequest
- type SourcePlugin
- type SubmissionPayload
- type Vault
- type Violation
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type AggregatedPolicy ¶
type AggregatedPolicy struct {
PolicyID string `json:"policy_id"`
ControlID string `json:"control_id"`
Status PolicyStatus `json:"status"`
Severity Severity `json:"severity"`
Category string `json:"category,omitempty"`
ResourcesEvaluated int `json:"resources_evaluated"`
ResourcesFailed int `json:"resources_failed"`
Message string `json:"message"`
RuleVersion string `json:"rule_version,omitempty"`
}
AggregatedPolicy is the per-policy projection that crosses the boundary. Counts only — no violation lists, no resource IDs. The Message string is regenerated from counts by the aggregator, never copied from the rule's violation text.
type AppliedException ¶ added in v0.20.0
type AppliedException struct {
PolicyID string `json:"policy_id"`
State string `json:"state"`
Reason string `json:"reason,omitempty"`
ApprovedBy string `json:"approved_by,omitempty"`
ApprovedAt string `json:"approved_at,omitempty"`
ExpiresAt string `json:"expires_at,omitempty"`
ResourceID string `json:"resource_id,omitempty"`
ResourcePattern string `json:"resource_pattern,omitempty"`
}
AppliedException is the snapshot of a planner-resolved exception that was in effect for the run. The shape mirrors spec.ExceptionConfig in .sigcomply.yaml, plus the resolved state and policy ID so an auditor reading the manifest doesn't need the project config to reconstruct who waived what and why.
type CIEnvironment ¶
type CIEnvironment struct {
Provider string `json:"provider"`
Workflow string `json:"workflow,omitempty"`
RunURL string `json:"run_url,omitempty"`
WorkerImage string `json:"worker_image,omitempty"`
}
CIEnvironment captures CI-runner metadata. Workflow names and run URLs are CI-system artifacts, not customer evidence.
type CloudClient ¶
type CloudClient interface {
Submit(ctx context.Context, payload SubmissionPayload) error
}
CloudClient transmits SubmissionPayload to a configured dashboard endpoint (SigComply Cloud or a self-hosted backend). It is the only consumer of SubmissionPayload outside the aggregator.
type Control ¶
type Control struct {
ID string
Name string
Description string
Category string
BaselineSeverity Severity
}
Control is one item in a framework's control catalog.
type Envelope ¶
type Envelope struct {
FormatVersion string `json:"format_version"`
ProducedAt time.Time `json:"produced_at"`
Records []EvidenceRecord `json:"records"`
Signature EnvelopeSignature `json:"signature"`
}
Envelope is the signed wrapper around a batch of EvidenceRecords. Every envelope is independently verifiable: the public key and signature live inside the envelope, so an auditor with one envelope file and nothing else can verify it offline.
type EnvelopeSignature ¶
type EnvelopeSignature struct {
Algorithm string `json:"algorithm"`
PublicKey []byte `json:"public_key"`
Value []byte `json:"value"`
}
EnvelopeSignature is the Ed25519 signature over canonical JSON of {format_version, produced_at, records}. The keypair is ephemeral — generated per envelope at write time and discarded the instant the signature is computed.
type EvidenceRecord ¶
type EvidenceRecord struct {
Type string `json:"type"`
ID string `json:"id"`
IdentityKey string `json:"identity_key,omitempty"`
Payload json.RawMessage `json:"payload"`
SourceID string `json:"source_id"`
CollectedAt time.Time `json:"collected_at"`
}
EvidenceRecord is one observation produced by a source plugin. IdentityKey is set only when the evidence type has a meaningful cross-source identity (e.g. an email for user_record across aws.iam and okta); leaving it empty disables cross-source dedup.
type EvidenceType ¶
type EvidenceType struct {
ID string `json:"id"`
Version int `json:"version"`
Schema json.RawMessage `json:"schema"`
}
EvidenceType is a versioned evidence-shape schema. The Schema is a JSON Schema document; collected records are validated against it before being wrapped in an Envelope.
type Framework ¶
type Framework interface {
ID() string
Version() string
Controls() []Control
Policies() []PolicyRef
}
Framework is a shipped or extension compliance framework — the catalog of controls plus the set of policies that contribute to each control.
type Manifest ¶
type Manifest struct {
SchemaVersion string `json:"schema_version"`
RunID string `json:"run_id"`
Framework string `json:"framework,omitempty"`
PeriodID string `json:"period_id,omitempty"`
StartedAt time.Time `json:"started_at"`
CompletedAt time.Time `json:"completed_at"`
FileHashes map[string]string `json:"file_hashes"`
ExceptionsApplied []AppliedException `json:"exceptions_applied,omitempty"`
Signature ManifestSignature `json:"signature"`
}
Manifest is the per-run signed integrity root. A single Ed25519 signature over FileHashes binds every file in the run folder; any later modification to a hashed file invalidates the manifest.
M5 shipped the minimal shape sufficient to sign and round-trip; later milestones layer optional fields on top (framework + period for reporting/integrity, exceptions_applied for the exception register view). See docs/architecture/05-vault-layout.md §Per-run manifest.
type ManifestSignature ¶
type ManifestSignature struct {
Algorithm string `json:"algorithm"`
PublicKey []byte `json:"public_key"`
Value []byte `json:"value"`
}
ManifestSignature mirrors EnvelopeSignature: a fresh ephemeral Ed25519 keypair is generated at signing time, the private key is zeroed immediately, and the public key is embedded so the manifest is independently verifiable.
type ParameterSpec ¶
type ParameterSpec struct {
Type string
Default any
Min any
Max any
Enum []any
Pattern string
Description string
}
ParameterSpec describes a tunable per-project value on a policy. Default/Min/Max/Enum are typed `any` because the value's static type is named by the Type field (bool, int, string, duration, …).
type Policy ¶
type Policy struct {
ID string
Control string
Description string
Remediation string
Severity Severity
Category string
Cadence string
OnPush bool
Slots map[string]Slot
Parameters map[string]ParameterSpec
RuleRef string
Tags []string
}
Policy is the fully-resolved spec used by the planner and evaluator. Specs are loaded from policy.yaml files at L0; this is the in-memory shape with the rule reference still as a string ID — the registry resolves it to a Rule implementation at plan time.
type PolicyRef ¶
type PolicyRef struct {
PolicyID string
}
PolicyRef points from a framework to a registered policy by ID. The PolicyRegistry resolves the ID to the full Policy spec.
type PolicyResult ¶
type PolicyResult struct {
PolicyID string
ControlID string
Status PolicyStatus
Severity Severity
Category string
EffectiveParams map[string]any
Violations []Violation
ResourcesEvaluated int
ResourcesFailed int
EvidenceEnvelopes []string
RuleVersion string
Diag map[string]any
}
PolicyResult is the per-policy outcome with full fidelity — includes violation details and resource IDs. This shape is what L7 (vault) persists. L6 (aggregator) projects it into the privacy-bounded AggregatedPolicy before any cloud submission.
PolicyResult is vault-side; nothing in this struct crosses the aggregation boundary directly.
type PolicyStatus ¶
type PolicyStatus string
PolicyStatus is the per-policy outcome of a run.
const ( StatusPass PolicyStatus = "pass" StatusFail PolicyStatus = "fail" StatusSkip PolicyStatus = "skip" StatusError PolicyStatus = "error" StatusNA PolicyStatus = "na" StatusWaived PolicyStatus = "waived" )
PolicyStatus values. `pass`/`fail` are the rule outcomes; `skip` / `error` / `na` / `waived` are evaluator/exception-driven states.
type Repository ¶
type Repository struct {
Provider string `json:"provider"`
NameSlug string `json:"name_slug"`
URL string `json:"url,omitempty"`
}
Repository is git-repo identity. Every field listed here is already public via the git remote URL.
type Rule ¶
Rule is the evaluation logic for a policy. Implementations may be hand-written Go, Rego (run via OPA), or a YAML DSL transpiled to Rego. Rules are pure functions over RuleInput — no I/O permitted.
type RuleInput ¶
type RuleInput struct {
PolicyID string
Slots map[string][]EvidenceRecord
Params map[string]any
Now time.Time
}
RuleInput is the read-only context handed to a rule per policy evaluation. Records arrive grouped by slot name.
type RuleResult ¶
type RuleResult struct {
Status PolicyStatus
Violations []Violation
Diag map[string]any
}
RuleResult is what a rule returns to the evaluator. Lives vault-side; the aggregator (L6) projects this into the privacy-bounded AggregatedPolicy that crosses the boundary.
type RunSummary ¶
type RunSummary struct {
PoliciesTotal int `json:"policies_total"`
PoliciesPassed int `json:"policies_passed"`
PoliciesFailed int `json:"policies_failed"`
PoliciesSkipped int `json:"policies_skipped"`
PoliciesError int `json:"policies_error"`
PoliciesNA int `json:"policies_na"`
PoliciesWaived int `json:"policies_waived"`
ComplianceScore float64 `json:"compliance_score"`
}
RunSummary is the counts-only run-level summary. ComplianceScore is the policies_passed / policies_total ratio, computed in the aggregator.
type Severity ¶
type Severity string
Severity is the policy's display severity. Set on the policy spec; a rule cannot override it. If a single policy needs variable severity, split it into multiple policies.
type Slot ¶
type Slot struct {
Type string
Cardinality SlotCardinality
Required bool
Description string
}
Slot is a named typed input on a policy — the interface between the policy and the source plugins that fulfill it.
type SlotCardinality ¶
type SlotCardinality string
SlotCardinality declares how many sources a slot may bind.
const ( SlotExactlyOne SlotCardinality = "exactly-one" SlotAtMostOne SlotCardinality = "at-most-one" SlotOneOrMore SlotCardinality = "one-or-more" SlotOptional SlotCardinality = "optional" )
SlotCardinality values. See 03-policy-spec.md §Slots for the project-binding rules each cardinality imposes.
type SlotRequest ¶ added in v0.19.0
type SlotRequest struct {
PolicyID string
EvidenceType string
SlotName string
Params map[string]any
}
SlotRequest is the per-binding call into a plugin's Collect. PolicyID is for diagnostics only — plugins must not branch behavior on it. EvidenceType is the slot's declared type and must match one of the plugin's Emits(); the planner enforces this at plan time. Params carries optional per-binding slot_params from the project config (rare; most bindings have no params).
type SourcePlugin ¶
type SourcePlugin interface {
ID() string
Emits() []string
Init(ctx context.Context, cfg map[string]any) error
Collect(ctx context.Context, req SlotRequest) ([]EvidenceRecord, error)
}
SourcePlugin produces EvidenceRecords for slots it can fulfill. Shipped plugins are compiled in; project-local plugins under .sigcomply/plugins/ are compiled in by `sigcomply build` (M16).
Implementations must:
- Sort emitted records by ID lexicographically before returning from Collect — keeps envelope bytes stable across runs when source state is stable.
- Set IdentityKey on EvidenceRecord when the evidence type has a meaningful cross-source identity (see 03-policy-spec.md §Cross-source dedup).
- Avoid embedding wall-clock timestamps in record payloads beyond what the source itself provides; use EvidenceRecord.CollectedAt for fetch time.
type SubmissionPayload ¶
type SubmissionPayload struct {
Schema string `json:"schema"`
RunID string `json:"run_id"`
Framework string `json:"framework"`
PeriodID string `json:"period_id"`
CommitSHA string `json:"commit_sha"`
CommitTime time.Time `json:"commit_time"`
Branch string `json:"branch"`
Repository Repository `json:"repository"`
Environment CIEnvironment `json:"environment"`
CLIVersion string `json:"cli_version"`
StartedAt time.Time `json:"started_at"`
CompletedAt time.Time `json:"completed_at"`
Summary RunSummary `json:"summary"`
Policies []AggregatedPolicy `json:"policies"`
}
SubmissionPayload is the wire format crossing the aggregation boundary from the customer environment to the cloud. Every field is concretely typed and represents either a count, an enum status, or already-public metadata.
SECURITY: This type is the structural privacy guarantee of the non-custodial architecture. Adding any field that could carry resource identity (ARNs, emails, IDs, file hashes, hostnames) is a non-custodial regression. Required for any such change:
- Written justification on the PR.
- Demonstration that the field cannot carry identity in any deployment.
- Review by >=2 maintainers including the security owner.
- Schema-version bump (sigcomply.cloud.v2).
The reflection test in cloud_test.go enforces "no freeform fields" structurally — adding interface{}, json.RawMessage, or map[string]any (transitively) will fail the build.
type Vault ¶
type Vault interface {
Init(ctx context.Context) error
PutEnvelope(ctx context.Context, path string, e *Envelope) error
PutJSON(ctx context.Context, path string, body any) error
PutBinary(ctx context.Context, path string, body []byte, meta map[string]string) error
GetBinary(ctx context.Context, path string) ([]byte, error)
List(ctx context.Context, prefix string) ([]string, error)
}
Vault is the customer-side persistence layer. Append-only per run; the CLI writes, auditors and dashboards read. Implementations are backend-specific (local, s3, gcs, azure_blob) but all conform to this interface.
The CLI never reads from the vault during the same run — vault is one-way for write-side flows.