Files
Qortal-Nextcloud-Integration/docs/engineering/chd-registration-domain-challenge-concept.md

5.8 KiB
Raw Permalink Blame History

CHD Registration Domain Challenge (Concept)

1. Purpose

Document a future hardening design for CHD installation registration that:

  1. Keeps new cloud setup mostly automatic
  2. Reduces abuse of open registration (/api/sovereign/v1/install/register)
  3. Preserves backward compatibility with current connector behavior

This is a design note only (not implemented yet).

2. Problem

Current registration can be fully automatic, which is good for UX.

Risk:

  1. If registration is open (no registration token required), attackers can spam fake installations.
  2. CHD may create registry/customer records for domains the caller does not control.
  3. Abuse can pollute instance registry, create noise in support/admin tooling, and consume resources.

3. Goals

  1. Prove caller controls the claimed public cloud domain.
  2. Keep first-run setup simple for legitimate users.
  3. Support both:
    • open registration mode (developer-friendly)
    • token-required registration mode (hardened production)
  4. Allow phased rollout without breaking existing installs.

4. Non-goals (for this phase)

  1. Proving Qortal address ownership cryptographically
  2. Preventing all abuse without rate limits or moderation
  3. Replacing CHD registration tokens entirely

Qortal ownership proof can be added later as a higher-trust layer (for grants/high-risk actions).

5. Proposed model

Use a two-step registration state:

  1. registered_unverified
  2. domain_verified

Optional later:

  1. qortal_verified
  2. billing_active

Registration may remain automatic, but higher-risk actions can require stronger state.

6. Domain challenge flow (proposed)

6.1 Step A: Initial registration request

Cloud calls:

  1. POST /api/sovereign/v1/install/register

Payload includes (as it does today):

  1. instanceId (optional client-supplied hint)
  2. nextcloudPublicUrl
  3. adminEmail (optional)
  4. adminQortalAddress (optional but recommended/used)
  5. mode/provider metadata

CHD response returns:

  1. normal instance credentials (instanceId, instanceToken, instanceSecret)
  2. registration state = registered_unverified
  3. a domain challenge object, e.g.:
    • challengeId
    • challengeToken
    • expiresAt
    • verifyPath (suggested URL path to expose)

6.2 Step B: Cloud proves domain control

Cloud exposes challenge token at a deterministic public URL under the claimed domain.

Examples:

  1. https://<cloud-domain>/.well-known/sovereign-chd/<instanceId>
  2. https://<cloud-domain>/apps/qortal_integration/api/chd/verify

CHD verifies by fetching that URL over HTTPS and matching the challenge token.

6.3 Step C: Verification result

If valid:

  1. CHD marks instance domain_verified
  2. CHD allows checkout issuance (recommended)
  3. CHD can elevate trust for later automation flows

If invalid/expired:

  1. instance remains registered_unverified
  2. CHD may allow only limited operations or block checkout

7. API sketch (proposed)

7.1 Registration response extension

Existing response can be extended without breaking clients:

{
  "ok": true,
  "registration": {
    "instanceId": "sc-example",
    "instanceToken": "…",
    "instanceSecret": "…"
  },
  "verification": {
    "state": "registered_unverified",
    "domainChallenge": {
      "required": true,
      "challengeId": "ch_123",
      "challengeToken": "abc123…",
      "verifyUrlPath": "/.well-known/sovereign-chd/sc-example",
      "expiresAt": "2026-02-24T00:00:00Z"
    }
  }
}

7.2 Optional explicit verify endpoint

CHD can verify passively by fetch, or also expose:

  1. POST /api/sovereign/v1/install/verify-domain

Input:

  1. instanceId
  2. optional challengeId

CHD performs fetch and returns status.

This helps plugin/admin UI display clearer status.

To keep UX smooth while reducing abuse:

  1. Registration:
    • allow open or token-required (configurable)
  2. Entitlements sync:
    • allow for registered instances
  3. Checkout link creation:
    • require domain_verified (recommended)
  4. Grant workflows / higher trust operations:
    • later require qortal_verified and/or manual review

9. Connector hardening controls (independent of challenge)

Domain challenge should be combined with basic anti-abuse controls:

  1. Rate limit registration by IP
  2. Rate limit by normalized domain
  3. Cooldown for repeated attempts per domain
  4. Expire unverified registrations (e.g. 1560 minutes)
  5. Reject localhost/private domains in production mode
  6. Cap pending unverified instances per IP/day
  7. Log registration + verification events

10. Backward compatibility / rollout

Phase 1 (compatibility)

  1. Add verification fields to registration response (optional)
  2. CHD stores verification state but does not enforce
  3. Existing plugins keep working unchanged

Phase 2 (soft enforcement)

  1. CHD warns on checkout when instance is not domain_verified
  2. Admin UI surfaces verification status and remediation steps

Phase 3 (policy enforcement)

  1. CHD blocks checkout for registered_unverified (configurable)
  2. Open registration remains possible but gated by verification

11. Future extension: Qortal ownership challenge

Longer term, add a second proof layer for the admin Qortal address:

  1. CHD issues a challenge tied to adminQortalAddress
  2. Admin proves control via Qortal-capable signing/decryption flow
  3. CHD marks instance qortal_verified

This is better suited to a CHD admin plugin/admin cloud with Qortal tooling, not the connector alone.

12. Open questions

  1. Which public challenge URL path is easiest and most stable for Nextcloud deployments?
  2. Should checkout require domain_verified immediately or only in production mode?
  3. Should verification use exact host match only, or allow canonical redirects?
  4. How long should challenge tokens remain valid?
  5. How should re-verification work when a cloud domain changes?