Operational DNS/TLD Policy Inside UCLS


0) Prereqs (one time)

  • Service endpoints (logical):
    • OaaS: POST /ucls/ontology/packs, GET/PUT /ucls/ontology/packs/{packId}
    • ProvAaaS: POST /ucls/provenance/sign, GET /ucls/provenance/{artifactDigest}
    • VaaS: POST /ucls/versions/releases, GET /ucls/versions/{id}
    • PRaaS/GaaS: POST /ucls/governance/opinions, POST /ucls/policy/bindings
    • ValaaS: POST /ucls/validations, POST /ucls/validation/gates
    • InteropaaS (adapters): /ucls/adapters/rdap|epp|doh|ct|dmarc|mta-sts|tls-rpt
    • DaaS/AnaaS/VizaaS: /ucls/graph/search, /ucls/analytics/*, /ucls/dashboards/*
  • Signing keys: Ed25519 (or P-256) org keypair, published as a DID (e.g., did:key:z6Mk…). Keep in HSM or KMS.
  • Policy packs on disk: the JSON/YAML packs we designed (ICANN-Core, .health, .gov, .edu, .mil, Brand, ccTLD template, Security Baseline, Email Auth, IDN Confusables, Phishing Defense).

1) Load packs into OaaS; sign via ProvAaaS

1.1 Upload as named artifacts (OaaS)

curl -sS -X POST https://ucls/api/ucls/ontology/packs \
  -H 'Content-Type: application/json' \
  -d @ICANN-Core-1.0.0.json
# → { "packId":"ICANN-Core", "version":"1.0.0", "artifactDigest":"sha256-…", "status":"stored" }

Repeat for:

  • TLD-Health@1.0.0.yaml
  • TLD-Gov@1.0.0.yaml
  • TLD-Edu@1.0.0.yaml
  • TLD-Mil@1.0.0.yaml
  • TLD-Brand-Starter@1.0.0.yaml
  • TLD-ccTLD-Template@1.0.0.yaml
  • Security-Baseline@1.0.0.yaml
  • Email-Auth-Baseline@1.0.0.yaml
  • IDN-Confusables@1.0.0.yaml
  • Phishing-Defense@1.0.0.yaml

1.2 Sign artifacts (ProvAaaS)

curl -sS -X POST https://ucls/api/ucls/provenance/sign \
  -H 'Content-Type: application/json' \
  -d '{
    "artifactDigest": "sha256-…",
    "signer": "did:key:z6Mk…",
    "purpose": "policy-pack",
    "claims": {"packId":"ICANN-Core","version":"1.0.0"}
  }'
# → { "signature":"…", "vc":"https://ucls/prov/vc/…", "signedAt":"2025-08-16T…Z" }

1.3 Link signature to pack + cut a versioned release (VaaS)

curl -sS -X POST https://ucls/api/ucls/versions/releases \
  -H 'Content-Type: application/json' \
  -d '{
    "subject": {"kind":"PolicyPack","id":"ICANN-Core@1.0.0"},
    "includes": ["signature:prov://…"],
    "notes":"Initial load",
    "labels":["dns","icann"]
  }'
# → { "releaseId":"vaas:rel:…", "status":"immutable" }

Rinse & repeat for all packs. From now on, packs are addressable, immutable, provable.


2) Attach packs by rule (TLD, sector, risk profile)

Create PolicyBindings that select resources and attach packs. Think K8s admission policies, but for names.

2.1 Binding schema (JSON-LD excerpt)

{
  "@type": "PolicyBinding",
  "bindingId": "bind:baseline-all",
  "selector": { "kind":"DomainName" },
  "packs": ["ICANN-Core@1.0.0","Security-Baseline@1.0.0","Email-Auth-Baseline@1.0.0","IDN-Confusables@1.0.0","Phishing-Defense@1.0.0"],
  "precedence": 10
}

2.2 TLD and sector-specific bindings

{
  "@type":"PolicyBinding",
  "bindingId":"bind:tld-health",
  "selector":{"kind":"DomainName","tld":".health"},
  "packs":["TLD-Health@1.0.0"],
  "precedence": 50
}
{
  "@type":"PolicyBinding",
  "bindingId":"bind:tld-gov",
  "selector":{"kind":"DomainName","tld":".gov"},
  "packs":["TLD-Gov@1.0.0"],
  "precedence": 50
}
{
  "@type":"PolicyBinding",
  "bindingId":"bind:risk-critical",
  "selector":{"kind":"DomainName","riskProfile":"critical"},
  "packs":["Security-Baseline@1.0.0"],
  "precedence": 60
}

2.3 Apply bindings (GaaS)

curl -sS -X POST https://ucls/api/ucls/policy/bindings \
  -H 'Content-Type: application/json' \
  -d @bind-baseline-all.json
curl -sS -X POST https://ucls/api/ucls/policy/bindings -d @bind-tld-health.json
curl -sS -X POST https://ucls/api/ucls/policy/bindings -d @bind-tld-gov.json
curl -sS -X POST https://ucls/api/ucls/policy/bindings -d @bind-risk-critical.json

Bindings appear in the governance graph, versioned by VaaS, signed by ProvAaaS.


3) Turn on ValaaS gates for DomainName/TLD

3.1 Gate definitions

{
  "gateId":"gate:domain-core",
  "targetKind":"DomainName",
  "shapes":["ucls:DomainNameShape","ucls:EmailSecurityShape","ucls:HTTPSPolicyShape"],
  "packs":["ICANN-Core@1.0.0","Security-Baseline@1.0.0","Email-Auth-Baseline@1.0.0","IDN-Confusables@1.0.0"],
  "failureMode":"fail-closed",
  "onFail":[{"action":"block-release"},{"action":"open-praas-case","severity":"high"}]
}
{
  "gateId":"gate:tld-core",
  "targetKind":"TLD",
  "shapes":["ucls:TLDShape","ucls:DNSSECAnchorShape"],
  "packs":["ICANN-Core@1.0.0"],
  "failureMode":"fail-closed"
}

3.2 Enable gates

curl -sS -X POST https://ucls/api/ucls/validation/gates \
  -H 'Content-Type: application/json' \
  -d @gate-domain-core.json

curl -sS -X POST https://ucls/api/ucls/validation/gates \
  -H 'Content-Type: application/json' \
  -d @gate-tld-core.json

From here on, any DomainName/TLD write (mint, bind, register, change) must pass these gates to release.


4) Wire adapters (RDAP/EPP, DoH/DNSSEC, CT, DMARC/MTA-STS/TLS-RPT)

You’ll run a small ingestion constellation. Each adapter emits signed Fact events into your bus (Kafka/NATS/Redpanda). ValaaS consumes facts during checks; ProvAaaS notarizes.

4.1 Topics

  • facts.rdap.v1, facts.epp.v1
  • facts.doh.dnssec.v1
  • facts.ct.monitor.v1
  • facts.mail.dmarc.rua.v1, facts.mail.mta-sts.v1, facts.mail.tls-rpt.v1

4.2 Event envelope (uniform)

{
  "factId":"fact:…",
  "kind":"rdap|epp|dnssec|ct|dmarc|mta-sts|tls-rpt",
  "observedAt":"2025-08-16T12:34:56Z",
  "subject":{"kind":"DomainName","id":"solveforce.health"},
  "payload":{…},
  "attestation":{"signer":"did:key:z6Mk…","sig":"…","hash":"sha256-…"}
}

4.3 RDAP ingestor

  • Config: registry RDAP base URIs, backoff, ETag caching.
  • Payload (example):
{
  "domain":"solveforce.health",
  "statuses":["active"],
  "events":[{"eventAction":"registration","eventDate":"2025-07-01T…Z"}],
  "nameservers":["ns1.solver.net","ns2.solver.net"],
  "entities":[{"role":"registrant","handle":"ORG-…"}]
}

4.4 EPP witness (read-only)

  • Subscribe to registrar/registry webhooks or escrow diffs.
  • Record create|renew|transfer|update|delete ops with transaction IDs.
  • Never store private keys—only proof of the op.

4.5 DoH prober (DNSSEC posture)

  • Resolve DNSKEY, DS, RRSIG, MX, CAA, TXT(_dmarc), HTTPS/SVCB.
  • Validate DNSSEC chain (root → TLD → domain).
  • Emit failures immediately; set severity:"critical" if DS/DNSKEY continuity breaks.

4.6 CT monitor

  • Subscribe to CT log aggregator.
  • Watch for new certs for the domain; compare CAA allowlist.
  • If mis-issuance suspected → open PRaaS case automatically.

4.7 DMARC/MTA-STS/TLS-RPT parsers

  • DMARC (RUA): parse XML aggregates, compute pass rate, alignments.
  • MTA-STS: fetch policy, check mode=enforce.
  • TLS-RPT: ingest failure reports, roll up per MX host.

4.8 Adapter registration (InteropaaS)

curl -X POST https://ucls/api/ucls/adapters/register \
  -H 'Content-Type: application/json' \
  -d '{
    "name":"rdap-ingestor",
    "topics":["facts.rdap.v1"],
    "healthProbe":"https://rdap-ingestor/health"
  }'

Once registered, gates can require fresh facts: e.g., “RDAP ≤ 24h old” or “DNSSEC proof ≤ 1h”.


5) Expose dashboards (posture score, confusable radar, dispute queue)

You can back these with ClickHouse/Postgres (facts table) + Prometheus (gauges). Panels can live in Grafana.

5.1 Storage sketch

  • Table domain_posture(domain, ts, dnssec_ok, dmarc_pass_rate, ct_gap_seconds, hsts_preload, caa_ok, spf_ok, dkim_ok, risk)
  • Table confusable_edges(domain_a, domain_b, score, script_pair, tld_a, tld_b, first_seen, status)
  • Table governance_cases(case_id, domain, type, opened_at, status, sla_deadline)

5.2 Posture score formula (example)

score = 100
- (dnssec_ok ? 0 : 30)
- penalty_for_dmarc(100 - dmarc_pass_rate)
- (ct_gap_seconds > 300 ? 10 : 0)
- (hsts_preload ? 0 : 5)
- (caa_ok ? 0 : 10)
clamp to [0, 100]

5.3 Example queries

  • Domains below SLO:
SELECT domain, ts, score
FROM domain_posture
WHERE ts > now() - INTERVAL 1 DAY AND score < 80
ORDER BY score ASC LIMIT 50;
  • Confusable radar (active threats):
SELECT domain_a, domain_b, score, status
FROM confusable_edges
WHERE status IN ('new','open') AND score >= 0.85
ORDER BY score DESC LIMIT 100;
  • Dispute queue SLA:
SELECT case_id, domain, type, status,
       DATE_DIFF('day', opened_at, now()) AS age_days,
       sla_deadline
FROM governance_cases
WHERE status IN ('open','pending') 
ORDER BY sla_deadline ASC;

5.4 Panels

  • Posture Heatmap: TLD on Y, metric on X, color by pass/fail.
  • Homoglyph Constellation: network graph (domain nodes, confusable edges).
  • UDRP/URS Timeline: gantt per case, SLA markers, PRaaS stage badges.

End-to-end smoke test (10 minutes)

  1. Mint token & bind anchors
curl -X POST https://ucls/api/ucls/names -d '{
  "token":{"value":"solveforce.health","kind":"domainName","components":{"unicode":"solveforce.health","punycode":"solveforce.health","tld":".health"}}
}'
# id: ucls:domain:…

curl -X POST https://ucls/api/ucls/anchors -d '{
  "subject":"ucls:domain:…",
  "anchor":{"kind":"dnssecChain","dsRecord":"…","dnskey":"…","rrsig":"…"},
  "rdap":"https://…/rdap/solveforce.health",
  "ctProofs":["ct:argon/entry/…"]
}'
  1. Validation gate run (should pass if packs satisfied)
curl -X POST https://ucls/api/ucls/validations -d '{"subject":"ucls:domain:…","gateId":"gate:domain-core"}'
# → { "status":"pass", "evidence":[…] }
  1. Release snapshot
curl -X POST https://ucls/api/ucls/versions/releases -d '{"subject":{"kind":"DomainName","id":"ucls:domain:…"},"labels":["health","dns"],"notes":"initial release"}'
  1. See posture & graph
curl -X GET "https://ucls/api/ucls/analytics/posture?domain=solveforce.health"
curl -X GET "https://ucls/api/ucls/graph/search?q=solveforce.health"

Guardrails & gotchas (the “don’t get cute” list)

  • Fail-closed on DNSSEC continuity and DMARC p=reject deadlines for health/finance/gov.
  • Bundle IDN variants to a single controller; block external look-alikes by default.
  • Registry lock for high-value labels; require out-of-band revocation.
  • CAA allowlist—watch CT constantly; mis-issuance auto-opens PRaaS.
  • No private keys ever in UCLS; we record facts and proofs, not secrets.

What you now have

  • All packs (ICANN Core + every extension) loaded, signed, and versioned.
  • Bindings that attach packs by TLD, sector, risk.
  • Gates that enforce the shapes and packs.
  • Adapters that feed cryptographic and operational facts.
  • Dashboards that measure posture, surface confusables, and drive disputes.