-
Notifications
You must be signed in to change notification settings - Fork 0
Configuring Gates
Tune the five gates for a realm: timeouts, ingress limits, the approval budget, sandbox limits, and arbitration. You tune gates — you do not reorder or disable them. This guide extends the GateConfig schema into concrete tasks; field names are the derived config model — reconcile against your build's schema.
Four rules hold throughout:
- Order is fixed. G0 → G4 always run in order; config changes their behavior, never their sequence or presence.
-
Changes are versioned. You bump a version (
gatecfg_v14→v15); the old one stays resolvable so historical decisions still replay. -
Fail-closed extends to config. An invalid gate config is rejected at admission — it does not run. Always
config validatebeforeapply. - Every change is provable. The version in force is pinned to each decision, so after any change you confirm it in Urd, not by hope.
Timeouts are deny ceilings, not latency targets — a gate that exceeds its budget denies.
timeouts: { ingress: 5s, policy: 10s, approval: 30s, sandbox: 60s, arbitration: 10s }
Why it is safe to raise sandbox: a longer sandbox timeout does not slow a healthy allow — it only delays the deny for a genuinely stuck sandbox. You are moving the fail-closed ceiling, not adding latency to the happy path.
Verify: after apply, a fresh decision's record carries the new config snapshot ID.
ingress:
rateLimit: { unit: tenant, tokens: 1000, refillPerSecond: 100 }
allowlist: ["10.0.0.0/8"]
maxBodyBytes: 1048576
Why: G0 denials are the cheapest in the pipeline — every request stopped here is one the expensive gates (G2, G3) never pay for. Rate-limit and shape aggressively.
Verify: exceed the limit and confirm 429 records appear:
norngate-cli audit query --gate ingress --decision deny --from now-5m
The rules themselves live in a Policy resource (default-deny, deny-overrides). The gate-side lever here is the deliberation budget:
# BudgetConfig
deliberation: { perAgentPerRequest: 50000, unit: tokens }
Why: G1 is deterministic and has no LLM in the decision — so a "policy denial" is always reproducible. The deliberation budget caps how much context an agent may pull before the decision, bounding cost per request. Author rules per Gates & Attributes.
Verify: dry-run before shipping —
norngate-cli policy test --subject retrieval-agent --resource pii:user-record --action write
approval:
riskThreshold: high # actions at or above this risk require G2
budget: { perTenantPerDay: 500 }
autoConsent:
- match: { action: read, resource.sensitivity: low }
Why: the approval budget is the lever that keeps human transits under ~5% of traffic. Raise riskThreshold and add autoConsent rules to route more low-risk actions through rule-based consent instead of a human — G2 stays reserved for what genuinely needs a person.
Verify: confirm the budget debits are landing:
norngate-cli audit query --gate approval --from now-1h
sandbox:
runtime: firecracker
limits: { cpu: "2", memory: 2Gi }
egress: brokered-only
warmPool: 16
Why egress: brokered-only: a sandbox that can open arbitrary outbound connections is an exfiltration channel. Brokering egress closes it. Why warmPool: G3 dominates end-to-end latency (~120ms warm); a warm pool avoids cold-start VM allocation on the hot path. Remember G3's fidelity limit — irreversible actions are prepared here and committed once at G4 (The Five Gates).
Verify: sandbox failures surface as 500:
norngate-cli audit query --gate sandbox --decision error --from now-15m
arbitration:
shardBy: resourceKey
lease: { ttl: 30s }
fairness: aging
Why fairness: aging: a purely deterministic winner would let a hot resource starve the writers that keep losing. Aging keeps the choice deterministic and starvation-free — deterministic is not the same as fair, and G4 owes you both.
Verify: contention shows up as 409, and commits as outcome records:
norngate-cli audit query --gate arbitration --from now-15m
Different realms want different gates. Target a realm with spec.realm and give each the budget its trust posture implies — a public Midgard gate rate-limits hard and sets a high approval threshold; an untrusted Jotunheim gate runs a longer sandbox and strict egress.
apiVersion: norngate.io/v1
kind: GateConfig
metadata: { name: midgard, version: gatecfg_v15 }
spec:
realm: midgard
timeouts: { ingress: 5s, policy: 10s, approval: 30s, sandbox: 60s, arbitration: 10s }
ingress: { rateLimit: { unit: tenant, tokens: 1000, refillPerSecond: 100 } }
approval: { riskThreshold: high, budget: { perTenantPerDay: 500 } }
sandbox: { runtime: firecracker, limits: { cpu: "2", memory: 2Gi }, egress: brokered-only }
arbitration: { shardBy: resourceKey, lease: { ttl: 30s }, fairness: aging }
The workflow is the same for any gate change:
# 1. validate (admission dry-run — fail-closed)
norngate-cli config validate midgard-gates.yaml
2. apply (new version)
norngate-cli config apply midgard-gates.yaml
3. verify — watch the decision shift, confirm the new version is pinned
norngate-cli audit query --realm midgard --from now-15m
4. roll back if wrong — re-pin the previous version
norngate-cli config apply --pin gatecfg_v14
Why this always works: if a change misbehaves, norngate-cli config diff gatecfg_v14 gatecfg_v15 shows exactly what moved, and the previous version is still resolvable — rollback is re-pinning, not reconstruction.
- Setting Up Subdomains (Realms) — the zones these gates run in.
- Gates & Attributes — authoring the policy G1 evaluates.
-
Configuration — the full
GateConfigschema. - The Five Gates — what each gate does and why it denies.
Section glyphs are Elder Futhark runes (Unicode Runic block, U+16A0–U+16FF) — semantic, not emoji. Full set on Home:
| Rune | Name | Gloss | Marks |
|---|---|---|---|
| ᚾ | Nauðiz | need, constraint | the platform mark |
| ᚨ | Ansuz | the word, instruction | before you start |
| ᛁ | Isa | ice, fixed ceilings | timeouts |
| ᚦ | Thurisaz | thorn, gateway | configuring each gate |
| ᛟ | Othala | enclosed estate, boundary | per-realm gates |
| ᛒ | Berkanan | growth, the change made | apply / verify / roll back |
| ᚱ | Raidō | the ride, the road | next steps |
References. Token-bucket rate limiting; NIST SP 800-162 + OASIS XACML (policy, per Gates & Attributes); Firecracker (G3 sandbox). Config model and CLI: Configuration, CLI Tools. Naming doctrine: Prose Edda / Poetic Edda, per Norse Cosmology & Platform Design.
Tune the five gates for a realm: timeouts, ingress limits, the approval budget, sandbox limits, and arbitration. You tune gates — you do not reorder or disable them. This guide extends the [GateConfig](https://claude.ai/chat/Configuration) schema into concrete tasks; field names are the derived config model — reconcile against your build's schema.
Four rules hold throughout:
- Order is fixed. G0 → G4 always run in order; config changes their behavior, never their sequence or presence.
-
Changes are versioned. You bump a version (
gatecfg_v14→v15); the old one stays resolvable so historical decisions still replay. -
Fail-closed extends to config. An invalid gate config is rejected at admission — it does not run. Always
config validatebeforeapply. - Every change is provable. The version in force is pinned to each decision, so after any change you confirm it in [Urd](Urd-Ledger), not by hope.
Timeouts are deny ceilings, not latency targets — a gate that exceeds its budget denies.
timeouts: { ingress: 5s, policy: 10s, approval: 30s, sandbox: 60s, arbitration: 10s }Why it is safe to raise sandbox: a longer sandbox timeout does not slow a healthy allow — it only delays the deny for a genuinely stuck sandbox. You are moving the fail-closed ceiling, not adding latency to the happy path.
Verify: after apply, a fresh decision's record carries the new config snapshot ID.
ingress:
rateLimit: { unit: tenant, tokens: 1000, refillPerSecond: 100 }
allowlist: ["10.0.0.0/8"]
maxBodyBytes: 1048576Why: G0 denials are the cheapest in the pipeline — every request stopped here is one the expensive gates (G2, G3) never pay for. Rate-limit and shape aggressively.
Verify: exceed the limit and confirm 429 records appear:
norngate-cli audit query --gate ingress --decision deny --from now-5mG1 — Policy
The rules themselves live in a Policy resource (default-deny, deny-overrides). The gate-side lever here is the deliberation budget:
# BudgetConfig
deliberation: { perAgentPerRequest: 50000, unit: tokens }Why: G1 is deterministic and has no LLM in the decision — so a "policy denial" is always reproducible. The deliberation budget caps how much context an agent may pull before the decision, bounding cost per request. Author rules per [Gates & Attributes](Gates-and-Attributes).
Verify: dry-run before shipping —
norngate-cli policy test --subject retrieval-agent --resource pii:user-record --action writeapproval:
riskThreshold: high # actions at or above this risk require G2
budget: { perTenantPerDay: 500 }
autoConsent:
- match: { action: read, resource.sensitivity: low }Why: the approval budget is the lever that keeps human transits under ~5% of traffic. Raise riskThreshold and add autoConsent rules to route more low-risk actions through rule-based consent instead of a human — G2 stays reserved for what genuinely needs a person.
Verify: confirm the budget debits are landing:
norngate-cli audit query --gate approval --from now-1hsandbox:
runtime: firecracker
limits: { cpu: "2", memory: 2Gi }
egress: brokered-only
warmPool: 16Why egress: brokered-only: a sandbox that can open arbitrary outbound connections is an exfiltration channel. Brokering egress closes it. Why warmPool: G3 dominates end-to-end latency (~120ms warm); a warm pool avoids cold-start VM allocation on the hot path. Remember G3's fidelity limit — irreversible actions are prepared here and committed once at G4 ([The Five Gates](The-Five-Gates)).
Verify: sandbox failures surface as 500:
norngate-cli audit query --gate sandbox --decision error --from now-15marbitration:
shardBy: resourceKey
lease: { ttl: 30s }
fairness: agingWhy fairness: aging: a purely deterministic winner would let a hot resource starve the writers that keep losing. Aging keeps the choice deterministic and starvation-free — deterministic is not the same as fair, and G4 owes you both.
Verify: contention shows up as 409, and commits as outcome records:
norngate-cli audit query --gate arbitration --from now-15mDifferent realms want different gates. Target a realm with spec.realm and give each the budget its trust posture implies — a public Midgard gate rate-limits hard and sets a high approval threshold; an untrusted Jotunheim gate runs a longer sandbox and strict egress.
apiVersion: norngate.io/v1
kind: GateConfig
metadata: { name: midgard, version: gatecfg_v15 }
spec:
realm: midgard
timeouts: { ingress: 5s, policy: 10s, approval: 30s, sandbox: 60s, arbitration: 10s }
ingress: { rateLimit: { unit: tenant, tokens: 1000, refillPerSecond: 100 } }
approval: { riskThreshold: high, budget: { perTenantPerDay: 500 } }
sandbox: { runtime: firecracker, limits: { cpu: "2", memory: 2Gi }, egress: brokered-only }
arbitration: { shardBy: resourceKey, lease: { ttl: 30s }, fairness: aging }The workflow is the same for any gate change:
# 1. validate (admission dry-run — fail-closed)
norngate-cli config validate midgard-gates.yaml
# 2. apply (new version)
norngate-cli config apply midgard-gates.yaml
# 3. verify — watch the decision shift, confirm the new version is pinned
norngate-cli audit query --realm midgard --from now-15m
# 4. roll back if wrong — re-pin the previous version
norngate-cli config apply --pin gatecfg_v14Why this always works: if a change misbehaves, norngate-cli config diff gatecfg_v14 gatecfg_v15 shows exactly what moved, and the previous version is still resolvable — rollback is re-pinning, not reconstruction.
- [Setting Up Subdomains (Realms)](Setting-Up-Subdomains-Realms) — the zones these gates run in.
- [Gates & Attributes](Gates-and-Attributes) — authoring the policy G1 evaluates.
- [Configuration](Configuration) — the full
GateConfigschema. - [The Five Gates](The-Five-Gates) — what each gate does and why it denies.
Section glyphs are Elder Futhark runes (Unicode Runic block, U+16A0–U+16FF) — semantic, not emoji. Full set on [Home](Home#iconography):
| Rune | Name | Gloss | Marks |
|---|---|---|---|
| ᚾ | Nauðiz | need, constraint | the platform mark |
| ᚨ | Ansuz | the word, instruction | before you start |
| ᛁ | Isa | ice, fixed ceilings | timeouts |
| ᚦ | Thurisaz | thorn, gateway | configuring each gate |
| ᛟ | Othala | enclosed estate, boundary | per-realm gates |
| ᛒ | Berkanan | growth, the change made | apply / verify / roll back |
| ᚱ | Raidō | the ride, the road | next steps |
References. Token-bucket rate limiting; [NIST SP 800-162](https://csrc.nist.gov/pubs/sp/800/162/final) + OASIS XACML (policy, per [Gates & Attributes](Gates-and-Attributes)); Firecracker (G3 sandbox). Config model and CLI: [Configuration](Configuration), [CLI Tools](CLI-Tools). Naming doctrine: Prose Edda / Poetic Edda, per [Norse Cosmology & Platform Design](Norse-Cosmology-and-Platform-Design).
Welcome
Getting Started
Core Concepts
Guides
- Guides
- Configuring Gates
- Setting Up Subdomains (Realms)
- Integrating AI Agents
- Monitoring & Observability
- Disaster Recovery (Ragnarök Drill)
- Custom Domains & TLS
Reference
Silence means no.