The HTTP door for the capture capability. Thin: authenticate → derive trust-zone origin → decode → capture.Service → map receipt to status. - Auth mirrors the chassis Bearer precedence (static token wins, then Dex JWT) but returns the resolved principal + auth path, which the chassis middleware hides — capture needs the principal to derive the origin. Depends on a small Validator interface (the chassis *JWTValidator satisfies it) so the JWT/origin path is testable without a live JWKS. - OriginResolver maps principal → trust zone: static-token caller and allowlisted JWT subjects → sovereign; every other principal → us-nexus (fail safe, so the I1 gate refuses confidential by default). Principal and origin are server-set on the input, overwriting any body the caller sent. - HTTP status: 200 all-ok / dry-run, 207 partial, 502 all-failed, 403 on the I1 refusal, 400 on fail-closed validation. - Wired in main behind the same static+JWT credentials as /mcp, reusing the MCP server's graph-wired brain store (one implementation) and the classification tags (#50). Mounts only when a Gitea tracker is configured. Sovereign JWT principals via BRAIN_CAPTURE_SOVEREIGN_PRINCIPALS. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
43 lines
1.5 KiB
Go
43 lines
1.5 KiB
Go
package capturehttp
|
|
|
|
import "github.com/mathiasbq/hyperguild/ingestion/internal/capture"
|
|
|
|
// OriginResolver maps an authenticated principal to its trust zone
|
|
// (spec §4.2). The mapping is server-side and never reads caller input.
|
|
//
|
|
// Rules:
|
|
// - The static-token path is a homelab CLI caller on sovereign soil →
|
|
// ZoneSovereign.
|
|
// - A JWT principal in the sovereign allowlist → ZoneSovereign.
|
|
// - Any other JWT principal (e.g. claude.ai's OAuth identity, or any
|
|
// unrecognised subject) → ZoneUSNexus.
|
|
//
|
|
// The default is the strict one: an unknown principal is treated as
|
|
// us-nexus so the I1 gate fails safe (refuses confidential), exactly as
|
|
// an untagged classification target fails safe to confidential (#50).
|
|
type OriginResolver struct {
|
|
sovereign map[string]bool
|
|
}
|
|
|
|
// NewOriginResolver builds a resolver whose JWT sovereign principals are
|
|
// the given subjects. The static-token caller is always sovereign and
|
|
// need not be listed.
|
|
func NewOriginResolver(sovereignPrincipals []string) OriginResolver {
|
|
m := make(map[string]bool, len(sovereignPrincipals))
|
|
for _, p := range sovereignPrincipals {
|
|
if p != "" {
|
|
m[p] = true
|
|
}
|
|
}
|
|
return OriginResolver{sovereign: m}
|
|
}
|
|
|
|
// Resolve returns the trust zone for a principal. viaStatic is true when
|
|
// the static-token auth path was taken.
|
|
func (r OriginResolver) Resolve(principal string, viaStatic bool) capture.Zone {
|
|
if viaStatic || r.sovereign[principal] {
|
|
return capture.ZoneSovereign
|
|
}
|
|
return capture.ZoneUSNexus
|
|
}
|