Documentation
¶
Overview ¶
Package auditspec is the policy model and evaluation engine for gowdk audit.
A Policy is a named, composable set of Rules applied to targets (routes, endpoints, contracts, or the frontend surface) selected by Selectors. The built-in Baseline encodes the production-readiness gates from docs/engineering/security.md; declared *.audit.gwdk policies extend or override it. Evaluate matches the policies against a securitymanifest posture and returns registry-coded Findings; it never decides severity — that comes only from internal/diagnostics.
Index ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func SortFindings ¶
func SortFindings(findings []Finding)
SortFindings orders findings deterministically by severity, code, then target.
Types ¶
type Finding ¶
type Finding struct {
Code string `json:"code"`
Severity diagnostics.Severity `json:"severity"`
CodeSource string `json:"codeSource,omitempty"`
Fingerprint string `json:"fingerprint,omitempty"`
Target string `json:"target,omitempty"`
Policy string `json:"policy,omitempty"`
Rule string `json:"rule,omitempty"`
Confidence string `json:"confidence,omitempty"`
Evidence string `json:"evidence,omitempty"`
CWE []string `json:"cwe,omitempty"`
OWASP []string `json:"owasp,omitempty"`
Suppression *Suppression `json:"suppression,omitempty"`
Message string `json:"message"`
Source string `json:"source,omitempty"`
Remediation string `json:"remediation,omitempty"`
}
Finding is one policy violation or policy-resolution error.
func EnrichFindings ¶ added in v0.8.0
EnrichFindings fills stable triage metadata on findings without changing the policy result itself. It is safe to call more than once.
func Evaluate ¶
func Evaluate(manifest securitymanifest.SecurityManifest, policies []Policy) []Finding
Evaluate matches policies against the posture manifest and returns findings. It first reports policy-resolution problems (cycles, unknown extends), then the per-target rule violations. Findings are returned in a stable order. Declared waivers are applied without digest pinning; use EvaluateWithWaivers to validate waivers against the current policy and posture digests.
func EvaluateWithWaivers ¶ added in v0.8.0
func EvaluateWithWaivers(manifest securitymanifest.SecurityManifest, policies []Policy, waiverCtx WaiverContext) []Finding
EvaluateWithWaivers is Evaluate with the current policy and posture digests so declared waivers that pin a digest can be validated against drift.
type Policy ¶
type Policy struct {
Name string
Extends []string
Selectors []Selector
Rules []Rule
Source string
Builtin bool
}
Policy is a named, composable set of rules applied to selected targets.
func Baseline ¶
func Baseline() []Policy
Baseline returns the built-in policy set that gowdk audit applies with zero configuration. It encodes the production-readiness gates from docs/engineering/security.md and docs/engineering/security-threat-model.md so security is enforced by default, not by opt-in. Declared *.audit.gwdk policies extend or override these via matching selectors and rules.
Severity is never set here; each rule references a registry code and the engine resolves severity from internal/diagnostics.
func ComposeBaseline ¶
ComposeBaseline returns the built-in baseline with declared policies appended.
Built-in baseline policies are monotonic: a declared policy can extend or tighten the baseline (with `extends`) or suppress a specific finding (with an explicit `waive`), but it can no longer silently replace a baseline policy by reusing its name. A same-name declared policy is kept here and reported by resolve as policy_baseline_override; its rules are not applied, so the baseline can never be weakened by omission. This keeps the fail-closed production story honest: removing a built-in error requires an attributable, expiring waiver.
func PoliciesFromIR ¶
PoliciesFromIR converts parsed *.audit.gwdk specs into engine policies.
type Rule ¶
Rule is one policy constraint. Code is the diagnostic code emitted when the rule is violated; Value carries the rule argument (a guard ID, header name, byte size, or allowlist entry) when the rule kind needs one. Source records where a declared rule originated so code-override validation can point at it.
type RuleKind ¶
type RuleKind string
RuleKind classifies one policy rule.
const ( // RuleRequireCSRF requires a matched endpoint to enforce CSRF. RuleRequireCSRF RuleKind = "require_csrf" // RuleRequireAnyGuard requires a matched target to state access (any guard, // including guard public) rather than be denied by omission. RuleRequireAnyGuard RuleKind = "require_any_guard" // RuleRequireGuard requires a specific guard ID (for example role:admin). RuleRequireGuard RuleKind = "require_guard" // RuleDenyPublic forbids guard public on a matched target. RuleDenyPublic RuleKind = "deny_public" // RuleMaxBody caps a matched endpoint's request body limit. RuleMaxBody RuleKind = "max_body" // RuleRequireRequestLimits requires a matched endpoint to declare an effective // request-limit posture: a positive raw body cap installed before the body is // parsed, and a multipart cap when multipart bodies are accepted. RuleRequireRequestLimits RuleKind = "require_request_limits" // RuleRequireHeader requires the app to be configured to emit a response // header. RuleRequireHeader RuleKind = "require_header" // RuleCheckSecurityHeaders audits the semantic strength of configured // security response headers (CSP, nosniff, Referrer-Policy, HSTS, framing). RuleCheckSecurityHeaders RuleKind = "check_security_headers" // RuleCheckCORS audits the generated cross-origin policy for risky // combinations such as a wildcard origin (optionally with credentials). RuleCheckCORS RuleKind = "check_cors" // RuleRequireClientRouteGuards reports client-visible routes that rely on // default-deny because the source declared no guard. RuleRequireClientRouteGuards RuleKind = "require_client_route_guards" // RuleNoSecretsInBundle forbids secret-shaped values in embedded output. RuleNoSecretsInBundle RuleKind = "no_secrets_in_bundle" // RuleDenyRawHTMLSinks reports every raw-HTML sink not allowlisted by a // RuleAllowRawHTML rule in any resolved frontend policy. RuleDenyRawHTMLSinks RuleKind = "deny_raw_html_sinks" // RuleAllowRawHTML allowlists one raw-HTML sink (source:field); every sink // not allowlisted is reported. This is the legacy coarse allowlist; prefer // RuleExceptRawHTML for an exact, justified, expiring exception. RuleAllowRawHTML RuleKind = "allow_raw_html" // RuleExceptRawHTML suppresses exactly one raw-HTML sink by its fingerprint, // and only when the exception carries an owner, justification, unexpired // expiry, and sanitizer/trusted-type contract. RuleExceptRawHTML RuleKind = "except_raw_html" // RuleDenyRolelessContract reports a web-exposed command or query contract // that declares no roles, so the data-layer authorization gate has no role to // admit. The contract must declare at least one role (or RoleAny to be // intentionally public). RuleDenyRolelessContract RuleKind = "deny_roleless_contract" // RuleRequireVerifiedGuards reports guards whose implementation is app-owned // and not backed by audit fixture evidence. RuleRequireVerifiedGuards RuleKind = "require_verified_guards" // RuleCheckObservability reports unsafe generated trace endpoint posture. RuleCheckObservability RuleKind = "check_observability" // RuleWaive suppresses one finding (by diagnostic code and target) when the // waiver carries an owner, justification, and unexpired expiry, and any pinned // policy/posture digest still matches. A waived finding is recorded with its // suppression metadata instead of blocking, so a suppression is always an // explicit, attributable, expiring decision rather than a silent override. RuleWaive RuleKind = "waive" )
type Selector ¶
type Selector struct {
Raw string
Kind SelectorKind
}
Selector targets a set of routes, endpoints, or the frontend surface.
func ParseSelector ¶
ParseSelector classifies a raw selector string.
type SelectorKind ¶
type SelectorKind string
SelectorKind classifies a policy target selector.
const ( SelectorRoute SelectorKind = "route" SelectorEndpoint SelectorKind = "endpoint" SelectorContract SelectorKind = "contract" SelectorObservability SelectorKind = "observability" SelectorFrontend SelectorKind = "frontend" SelectorUnknown SelectorKind = "unknown" )
type Summary ¶
type Summary struct {
Errors int `json:"errors"`
Warnings int `json:"warnings"`
Info int `json:"info"`
Waived int `json:"waived"`
}
Summary counts findings by severity. Waived findings (suppressed by an explicit waiver) are counted only under Waived so a justified, unexpired suppression does not block, while the suppression stays recorded in the report.
type Suppression ¶ added in v0.8.0
type Suppression struct {
Owner string `json:"owner,omitempty"`
Justification string `json:"justification,omitempty"`
Expires string `json:"expires,omitempty"`
Ticket string `json:"ticket,omitempty"`
DigestScope string `json:"digestScope,omitempty"`
}
Suppression is reserved for explicit waiver records once the audit DSL grows waiver syntax. Keeping the shape in JSON now lets downstream tooling preserve the field without inventing an incompatible suppression contract later.
type Waiver ¶ added in v0.8.0
type Waiver struct {
Code string
Target string
Owner string
Justification string
Expires string
Ticket string
PolicyDigest string
PostureDigest string
Policy string
Source string
}
Waiver is one declared `waive` rule: an explicit, attributable, expiring decision to suppress a specific finding by diagnostic code and target. A waiver only suppresses when it carries an owner, justification, and unexpired expiry, and when any pinned policy/posture digest still matches the current build. Invalid or stale waivers are reported instead of silently doing nothing.
type WaiverContext ¶ added in v0.8.0
WaiverContext carries the current policy and posture digests so a waiver that pins a digest can be invalidated when the policy set or posture drifts. A zero Now falls back to the package clock.