Skip to main content

DB-TAB

ZAYAZ Domain Strategy (MDX)

Overview​

This document defines the domain architecture for the ZAYAZ ecosystem. Domains are treated as infrastructure primitives, not just branding assets. Each domain maps to:

  • Environment (prod, dev, sandbox)
  • Trust level (public, regulated, internal)
  • System layer (core, AI, partner, education)

Owned Domains (Authoritative Inventory)​

zayaz.io
zayaz.dev
zayaz.cloud
zayaz.ai

ecoworld.ai
eco-number.com
eco-number.org
e-c-o.com

viroway.com

sustainability-act.org

Domain Role Classification​

DomainRoleLayerTrust Level
zayaz.ioCore platformProductionHigh (regulated)
zayaz.devDev + sandboxDevelopmentInternal
zayaz.cloudWhite-label infraPartnerMedium–High
zayaz.aiAI positioningAI layerMedium
ecoworld.aiEducation + public ESGEcosystemPublic
eco-number.comPublic ESG lookupTrust layerPublic
eco-number.orgNGO/regulatory mirrorTrust layerPublic/Institutional
e-c-o.comBrand/media/SEOEcosystemPublic
viroway.comCorporateCorporatePublic
sustainability-act.orgPolicy/legislationGovernancePublic/Institutional

Core Principles​

1. Environment Isolation​

Each environment must be strictly separated at the domain level.

  • Production must never share domains with development
  • Sandbox must be explicitly identifiable

2. Trust Zoning​

ZoneDescriptionExamples
PublicOpen access, low trust barriereco-number.com
RegulatedClient-facing, compliance-criticalapp.zayaz.io
InternalRestricted, experimental*.zayaz.dev

3. Functional Mapping​

Each domain must have a single clear responsibility.


Domain Layers​

1. Core Platform (Production)​

zayaz.io
app.zayaz.io
api.zayaz.io

Purpose:

  • ESG reporting (CSRD/ESRS)
  • Client dashboards
  • Core APIs

2. Development & Sandbox​

zayaz.dev
api.zayaz.dev
sandbox.zayaz.dev
lab.zayaz.dev
agents.zayaz.dev

Purpose:

  • Safe experimentation
  • Partner testing
  • AI agent development (ZAAM/ZARA)

3. Public Trust Layer​

eco-number.com
eco-number.org

Purpose:

  • Public ESG lookup
  • Supplier transparency
  • NGO / regulator access

4. Education & Ecosystem​

ecoworld.ai
academy.zayaz.io
e-c-o.com

Purpose:

  • ESG education
  • Academy modules
  • Thought leadership

5. Partner & White-Label Layer​

zayaz.cloud
partners.zayaz.cloud

Pattern:

<client>.zayaz.cloud

Redirecting host:

  • public client-facing redirect host:
    • <client>.zayaz.cloud/<Primary Code>
  • runtime/API target:
    • region-specific app endpoint, for example:
      • https://api.eu-central-1.zayaz.io/...
      • https://api.ap-northeast-3.zayaz.io/...

Purpose:

  • zayaz.cloud is the branded client entry layer
  • zayaz.io is the application/service layer
  • routing use client metadata to decide region/tenant target
  • we avoid overloading www.zayaz.io

6. AI Layer​

zayaz.ai
ai.zayaz.io
zara.zayaz.ai

7. Corporate Layer​

viroway.com

Purpose:

  • Corporate identity
  • Investor relations
  • Legal entity

8. Governance / Policy Layer (Strategic)​

sustainability-act.org

Purpose:

  • Legislative proposals
  • ESG policy frameworks
  • NGO / institutional engagement

Environment Architecture​

Production​

app.zayaz.io
api.zayaz.io
ai.zayaz.io

Development​

api.zayaz.dev
sandbox.zayaz.dev
agents.zayaz.dev

Internal​

internal.zayaz.io
admin.zayaz.io

AI Governance Domains​

ai.zayaz.dev       # model testing
ai.zayaz.io # production AI

audit.zayaz.io # audit dashboards

Developer Ecosystem​

zayaz.dev/docs
zayaz.dev/playground
zayaz.dev/sandbox

DNS & Routing Strategy (Cloudflare-Centric)​

Stack​

  • Cloudflare DNS (authoritative)
  • Cloudflare Workers (edge routing)
  • Cloudflare KV / D1 (config + redirect mapping)
  • API Gateway (internal service mesh)

Example Routing Table​

DomainTarget
api.zayaz.ioAPI Gateway (prod cluster)
api.zayaz.devDev cluster
sandbox.zayaz.devSandbox compute cluster
app.zayaz.ioFrontend (prod)
ecoworld.aiPublic frontend

Security Model​

  • HTTPS enforced globally (.dev already HSTS)
  • Separate auth providers per environment
  • Zero trust between dev and prod
  • Strict CORS policies per domain

Anti-Patterns (Avoid)​

❌ Mixing environments:

dev.zayaz.io + zayaz.dev

❌ Multi-purpose domains

❌ Inconsistent naming


Roadmap​

Phase 1 (Current)​

  • zayaz.io
  • zayaz.dev
  • zayaz.cloud
  • zayaz.ai
  • ecoworld.ai
  • eco-number.com
  • eco-number.org
  • e-c-o.com
  • viroway.com
  • sustainability-act.org

Phase 2​

  • Developer portal expansion
  • Partner provisioning via zayaz.cloud
  • AI productization via zayaz.ai

Phase 3​

  • Policy platform scaling (splt-act)
  • Global ESG identity federation

Infrastructure Specification​

Objective​

Define a deployable, environment-isolated, Cloudflare-centric infrastructure model for the ZAYAZ ecosystem, including DNS, routing, edge services, API segmentation, security boundaries, and white-label provisioning.


1. Infrastructure Design Principles​

1.1 Production and Development Must Be Physically and Logically Separated​

Separation must exist at all layers:

  • DNS zones and subdomains
  • authentication audiences
  • API gateways
  • databases and storage
  • secrets
  • telemetry streams
  • deployment pipelines

Development systems must never share production credentials, production data stores, or production event pipelines.

1.2 Edge-First Routing​

Cloudflare should act as the front-door control plane for:

  • DNS
  • TLS termination
  • WAF
  • bot protection
  • redirect services
  • edge routing
  • worker-based request shaping

1.3 Service-Oriented Internal Architecture​

All major platform capabilities should sit behind explicit service boundaries.

Examples:

  • identity service
  • API gateway
  • reporting service
  • FOGE service
  • SSSR service
  • AI orchestration service
  • MICE execution service
  • public trust lookup service
  • partner provisioning service

1.4 Domain Responsibility Must Mirror System Responsibility​

Each domain or subdomain must correspond to a clear runtime role:

  • user interface
  • API endpoint
  • documentation portal
  • sandbox runtime
  • public lookup
  • partner tenant ingress

2. Target Platform Topology​

2.1 Internet-Facing Domain Map​

viroway.com               → Corporate site
zayaz.io → Main product entry
app.zayaz.io → Main authenticated SaaS UI
api.zayaz.io → Production public API gateway
admin.zayaz.io → Restricted admin UI
partners.zayaz.io → Partner onboarding and control plane
academy.zayaz.io → Academy entry / redirect or app
ai.zayaz.io → Production AI service ingress
audit.zayaz.io → Audit / trust / lineage dashboards

zayaz.dev → Developer portal root
api.zayaz.dev → Development API gateway
sandbox.zayaz.dev → Sandbox runtime for partners and internal QA
agents.zayaz.dev → Agent-mode testing UI / API
lab.zayaz.dev → Experimental engines and prototypes
docs.zayaz.dev → Developer docs
playground.zayaz.dev → API playground / token-safe testing

zayaz.cloud → White-label landing / partner infra anchor
<tenant>.zayaz.cloud → White-label tenant ingress

zayaz.ai → AI product positioning / marketing / future AI surface
zara.zayaz.ai → AI-first interface (future)

ecoworld.ai → Public-facing ESG ecosystem / Academy / thought leadership
eco-number.com → Primary public company lookup portal
eco-number.org → Institutional / NGO / mirrored trust portal
e-c-o.com → Editorial / public education / SEO layer

sustainability-act.org → Policy / legislation proposal hub

3. Zone Strategy​

Each of the following should be maintained as a separately governed DNS zone:

  • zayaz.io
  • zayaz.dev
  • zayaz.cloud
  • zayaz.ai
  • ecoworld.ai
  • eco-number.com
  • eco-number.org
  • e-c-o.com
  • viroway.com
  • sustainability-act.org

3.2 Zone Governance Rules​

Each zone should have:

  • dedicated ownership metadata
  • change logging
  • least-privilege DNS access
  • registrar lock where available
  • DNSSEC enabled where supported
  • Cloudflare-proxied records by default unless there is a specific reason not to proxy

3.3 Naming Conventions​

Use a stable naming convention across all platform domains:

  • app = primary end-user application
  • api = API gateway
  • admin = restricted operator interface
  • docs = documentation
  • sandbox = safe partner / test environment
  • audit = auditability surfaces
  • partners = partner control plane
  • ai = production AI ingress
  • agents = agent-specific testing/runtime
  • lab = experimental surfaces

4. Cloudflare Control Plane​

4.1 Cloudflare Services to Use​

Recommended baseline:

  • DNS
  • Universal or Advanced SSL
  • WAF managed rules
  • Rate limiting
  • Zero Trust access policies
  • Workers
  • KV for lightweight configuration/redirects
  • D1 for small operational control-plane tables if needed
  • R2 for static file/object delivery if appropriate
  • Tunnel for selected internal admin origins if needed
  • Turnstile for abuse-sensitive forms
  • Logpush for security and request logging

4.2 Edge Routing Model​

Cloudflare Workers should be used for:

  • canonical redirects
  • hostname-based routing
  • lightweight auth pre-checks
  • feature flag routing at the edge
  • request normalization
  • short-link and academy redirects
  • public lookup caching and shaping

Workers should not become the primary business logic layer for heavy ESG computation. That logic belongs in core services behind the gateway.


5. Environment Model​

5.1 Production Environment​

Production serves regulated, client-facing, business-critical workloads.

Primary endpoints:

app.zayaz.io
api.zayaz.io
ai.zayaz.io
audit.zayaz.io
partners.zayaz.io

Production rules:

  • production-only identity provider audiences
  • production-only secrets store
  • production-only databases
  • production-only message buses
  • production-only telemetry projects
  • strong WAF and rate-limiting policies
  • human-reviewed deployment approvals for critical services

5.2 Development Environment​

Development exists for engineering integration, agent iteration, and QA.

Primary endpoints:

api.zayaz.dev
sandbox.zayaz.dev
agents.zayaz.dev
lab.zayaz.dev
docs.zayaz.dev
playground.zayaz.dev

Development rules:

  • no production data by default
  • synthetic or masked data only
  • ephemeral preview deployments allowed
  • broader observability and debugging enabled
  • lower trust tier than production

5.3 Sandbox Environment​

Sandbox is a separately governed surface for:

  • partner API testing
  • verifier integration testing
  • white-label validation
  • SDK experimentation
  • demo environments with safe data

Recommended endpoint:

sandbox.zayaz.dev

Sandbox rules:

  • isolated tenant namespace
  • isolated credentials and tokens
  • documented API limits
  • seeded sample organizations and reports
  • easy environment reset and replay

5.4 Internal / Restricted Operations​

Restricted operator endpoints:

admin.zayaz.io
internal.zayaz.io
ops.viroway.com

These should sit behind Cloudflare Zero Trust or equivalent identity-aware access controls.


6. Application and Service Segmentation​

6.1 Frontend Surfaces​

SurfaceDomainPurpose
Product marketingzayaz.ioProduct entry, narrative, conversion
Main appapp.zayaz.ioAuthenticated client UI
Admin consoleadmin.zayaz.ioRestricted platform administration
Partner control planepartners.zayaz.ioWhite-label setup, keys, billing, domains
Developer docsdocs.zayaz.devAPI docs, SDK docs, schemas
Playgroundplayground.zayaz.devSafe testing interface
Public lookupeco-number.comPublic ESG lookup
Institutional mirroreco-number.orgNGO/regulatory oriented lookup
Academyacademy.zayaz.io / ecoworld.aiEducation and learning journeys

6.2 Gateway Layer​

Two gateway tiers are recommended:

Production Gateway​

api.zayaz.io

Purpose:

  • enforce auth
  • route to service mesh / internal services
  • validate versioned API contracts
  • apply quotas and rate limits
  • centralize audit and telemetry

Development / Sandbox Gateway​

api.zayaz.dev
sandbox.zayaz.dev

Purpose:

  • non-production API traffic
  • partner testing
  • experimental contract rollout
  • pre-release schema verification

6.3 Core Internal Service Domains (Logical)​

These do not need public DNS but should exist as formal service boundaries:

  • Identity Service
  • Tenant Service
  • Billing Service
  • SSSR Service
  • ZAR / artifact registry service
  • FOGE Service
  • Reporting Service
  • XBRL Export Service
  • MICE Execution Service
  • Validation / Trust Service
  • AI Orchestration Service (ZAAM/ZADIF/ZARA runtime)
  • Audit / Lineage Service
  • Public Lookup Service
  • Notification Service
  • Partner Provisioning Service

7. Network and Request Flow​

7.1 Canonical Request Flow for SaaS App​

User
↓
Cloudflare DNS
↓
Cloudflare Edge (TLS, WAF, bot filtering, rate limits)
↓
app.zayaz.io frontend
↓
api.zayaz.io gateway
↓
internal service mesh / service router
↓
service-specific backends and data stores

7.2 Canonical Request Flow for Public Lookup​

User / NGO / Stakeholder
↓
eco-number.com
↓
Cloudflare Edge + Worker cache logic
↓
Public Lookup Service
↓
read-optimized public trust dataset

7.3 Canonical Request Flow for Partner Sandbox​

Partner Developer
↓
sandbox.zayaz.dev
↓
Cloudflare Edge
↓
Sandbox Gateway
↓
Sandbox tenant services + synthetic/sample data

8. Identity and Access Architecture​

8.1 Identity Separation​

Identity must be environment-scoped.

Minimum split:

  • production audience / issuer for *.zayaz.io
  • development audience / issuer for *.zayaz.dev
  • partner-scoped identities for white-label operations
  • internal operator identities for admin.zayaz.io and restricted surfaces

8.2 Access Tiers​

Access TierExamplesControls
Publiceco-number.com, ecoworld.aino login or light auth
Client Authenticatedapp.zayaz.ioSSO / MFA / RBAC
Partner Authenticatedpartners.zayaz.io, zayaz.cloud control planeSSO / MFA / scoped keys
Operator Restrictedadmin.zayaz.ioZero Trust + MFA + device checks
Machine-to-Machineapi.zayaz.iosigned tokens, mTLS or equivalent where needed

8.3 RBAC / ABAC Principles​

Use role-based access control enriched by attribute-based rules for:

  • tenant
  • verifier role
  • regulator/NGO role
  • jurisdiction
  • framework scope
  • data sensitivity level
  • audit access rights

9. White-Label Infrastructure Model​

9.1 Primary White-Label Pattern​

Use zayaz.cloud as the infrastructure anchor.

Pattern:

<tenant>.zayaz.cloud

Examples:

partnera.zayaz.cloud
verifierhub.zayaz.cloud
clientdemo.zayaz.cloud

9.2 White-Label Provisioning Workflow​

  1. Create tenant record in Tenant Service
  2. Allocate tenant slug
  3. Provision DNS record under zayaz.cloud
  4. Issue TLS automatically via Cloudflare
  5. Attach tenant branding config
  6. Attach tenant auth config / SSO metadata
  7. Bind tenant to API scopes and storage namespaces
  8. Emit audit event for provisioning

9.3 Custom Domain Support (Future)​

Allow enterprise partners to bring their own domain later, for example:

esg.partnername.com

Model:

  • partner verifies domain ownership
  • CNAME or delegated setup
  • tenant mapping added to control plane
  • edge routing maps custom hostname to correct tenant

9.4 Control Plane Endpoint​

Recommended partner control plane:

partners.zayaz.io

Functions:

  • manage tenants
  • create API keys
  • configure webhooks
  • upload branding assets
  • configure custom domains
  • view audit history
  • manage sandbox access

10. AI and Agent Runtime Architecture​

10.1 Domain Separation for AI​

Production AI ingress:

ai.zayaz.io

Development/testing AI ingress:

ai.zayaz.dev
agents.zayaz.dev

Future AI-facing public product surface:

zara.zayaz.ai

10.2 Runtime Segmentation​

Separate:

  • prompt orchestration
  • model adapters
  • trust scoring
  • agent routing
  • audit logging
  • retrieval / policy retrieval
  • sandboxed experiments

10.3 Governance-Critical Rule​

No experimental agent or model runtime under *.zayaz.dev may call production compliance-critical execution paths without an explicit brokered approval layer.

10.4 Audit Surfaces​

Recommended:

audit.zayaz.io

Scope:

  • lineage views
  • trust score trails
  • AI-origin tagging visibility
  • model version references
  • validation decision history

11. Data and Storage Segmentation​

11.1 Storage Categories​

Separate storage by purpose:

  • operational relational data
  • analytics / warehouse data
  • document / artifact storage
  • audit log storage
  • public trust dataset
  • sandbox sample data
  • AI evaluation datasets

11.2 Environment Rules​

Production and development must not share:

  • primary databases
  • object storage buckets
  • signing keys
  • queue namespaces
  • analytics workspaces unless explicitly partitioned

11.3 Public Dataset Strategy​

For eco-number.com and eco-number.org, expose a deliberately curated, read-optimized public dataset rather than querying regulated production application tables directly.


12. Observability and Logging​

12.1 Core Observability Streams​

Maintain separate observability channels for:

  • edge request logs
  • application logs
  • audit logs
  • security logs
  • AI runtime traces
  • partner provisioning logs
  • schema and routing change logs

12.2 Environment Isolation​

Use separate telemetry projects or namespaces for:

  • production
  • development
  • sandbox
  • internal operations

12.3 Minimum Dashboards​

Required dashboards:

  • edge traffic and attack patterns
  • API latency and error rates
  • tenant health
  • agent / AI trust events
  • public lookup performance
  • partner provisioning status
  • audit event throughput

13. Security Controls​

13.1 Baseline Controls​

  • TLS everywhere
  • HSTS on all eligible domains
  • WAF managed rules enabled
  • rate limiting on public APIs
  • bot mitigation on public forms and lookup endpoints
  • secret rotation policy
  • MFA for operators and partners
  • Zero Trust access for admin surfaces
  • signed webhooks with replay protection

13.2 Sensitive Surfaces​

Highest protections should apply to:

  • admin.zayaz.io
  • api.zayaz.io
  • partners.zayaz.io
  • audit.zayaz.io
  • white-label provisioning paths

13.3 CORS Strategy​

Never use permissive wildcard CORS for regulated APIs.

Maintain explicit allowlists per environment and per product surface.


14. DNS Record Blueprint​

14.1 Example High-Level Record Plan​

zayaz.io​

  • apex → marketing / landing frontend
  • app → authenticated SaaS frontend
  • api → production gateway
  • admin → restricted admin frontend
  • partners → partner control plane
  • academy → academy service / redirect worker
  • ai → production AI ingress
  • audit → audit dashboards

zayaz.dev​

  • apex → developer portal
  • api → dev gateway
  • sandbox → sandbox runtime
  • agents → agent runtime / UI
  • lab → experimental apps
  • docs → docs site
  • playground → playground UI
  • ai → model test ingress

zayaz.cloud​

  • apex → white-label info / partner landing
  • wildcard * → tenant ingress routing

eco-number.com​

  • apex → public lookup frontend
  • api (optional) → public lookup API

ecoworld.ai​

  • apex → public ecosystem site
  • academy (optional if not using academy.zayaz.io) → learning experience

15. Deployment and Release Model​

  1. local development
  2. preview / ephemeral branch environment
  3. shared development (*.zayaz.dev)
  4. sandbox certification environment
  5. production (*.zayaz.io)

15.2 Critical Release Rules​

Production releases affecting:

  • reporting
  • public trust data
  • AI governance
  • partner provisioning
  • auth

should require structured approval, automated tests, and audit logging.

15.3 Infrastructure as Code​

All DNS, Workers, routing rules, WAF rules, and tenant provisioning workflows should be managed via Infrastructure as Code.

Preferred categories:

  • Terraform or Pulumi for cloud and DNS resources
  • Wrangler-managed Worker deployments
  • version-controlled environment manifests

Phase A — Core Production and Dev Separation​

Implement first:

zayaz.io
app.zayaz.io
api.zayaz.io
admin.zayaz.io
zayaz.dev
api.zayaz.dev
sandbox.zayaz.dev
docs.zayaz.dev

Phase B — Public Trust and Education Layer​

Implement:

eco-number.com
eco-number.org
ecoworld.ai
academy.zayaz.io

Phase C — White-Label Control Plane​

Implement:

partners.zayaz.io
zayaz.cloud
*.zayaz.cloud

Phase D — AI and Audit Surfaces​

Implement:

ai.zayaz.io
audit.zayaz.io
agents.zayaz.dev
ai.zayaz.dev
zara.zayaz.ai

Phase E — Policy and Governance Outreach​

Implement:

sustainability-act.org

as a separate policy narrative platform, not as part of the regulated app stack.


17. Decisions to Lock Early​

The following decisions should be locked early to prevent future architectural drift:

  1. zayaz.io is the regulated product root
  2. zayaz.dev is the only non-production engineering root
  3. zayaz.cloud is the white-label tenant namespace
  4. eco-number.com is the primary public trust portal
  5. ecoworld.ai is the public education and ecosystem brand
  6. viroway.com remains the corporate/legal layer
  7. sustainability-act.org remains policy/governance, not product runtime

18. Tenant Routing & Resolution Architecture​

All tenant-facing domains under zayaz.cloud are resolved dynamically using a hostname → tenant mapping layer implemented at the edge.

18.1. DNS Layer (Cloudflare)​

*.zayaz.cloud → tenant-edge-router (Cloudflare Worker)

- Wildcard DNS routes all tenants to a shared ingress
- No per-tenant DNS record required for standard onboarding
- Custom domains (future) may override this behavior

18.2. Edge Routing (Cloudflare Worker)​

The Worker performs:

  1. Extract hostname → acme.zayaz.cloud
  2. Lookup in KV:

key = "acme.zayaz.cloud"

  1. Retrieve tenant configuration
  2. Attach tenant context to request
  3. Route to appropriate origin (origin_target)

18.3. KV Payload Structure​

kv-payload-structure.jsonGitHub ↗
{
"client_id": "eco-173-123-456-789",
"tenant_slug": "acme",
"hostname": "acme.zayaz.cloud",
"status": "active",
"origin_target": "app_prod",
"css_sssr_ref": "sssr:asset.client-profiles.css.css @ eco-173-123-456-789",
"logo_sssr_ref": "sssr:asset.client-profiles.main-logo.gif @ eco-173-123-456-789",
"auth_profile_id": "auth_acme_v1"
}

18.4. Key Design Principles​

  • KV stores references, not assets or URLs
  • All branding is resolved via SSSR
  • Hostname determines tenant before authentication
  • Tenant resolution must be:
    • deterministic
    • low-latency
    • globally available

19. Branding Resolution via SSSR​

Tenant branding is not stored in KV as raw values.

Instead, KV stores SSSR references, which are resolved at runtime.


19.1. CSS Resolution​

"css_sssr_ref": "sssr:asset.client-profiles.css.css @ eco-173-123-456-789"

Runtime flow:

  1. Worker passes css_sssr_ref to frontend
  2. Frontend (or resolver API) resolves SSSR reference
  3. CSS file is loaded dynamically

19.2. Logo Resolution

logo-resolution.jsonGitHub ↗
{
"logo_sssr_ref": "sssr:asset.client-profiles.main-logo.gif @ eco-173-123-456-789"
}

Resolved via:

sssr → asset registry → path_template → CDN URL


19.3. Benefits​

  • No hardcoded branding values
  • Full auditability via SSSR
  • Easy rebranding (change asset, not references)
  • CDN/provider independence
  • Supports:
    • theming
    • localization
    • versioning

20. Tenant Onboarding Flow (Automated)​

Tenant onboarding must be fully automatable and exportable.


20.1. Input (Control Plane)​

New tenant created in AWS:

client_id = eco-173-123-456-789
tenant_slug = acme
hostname = acme.zayaz.cloud

20.2. KV Record Generation​

Generated automatically:

kv-record-generation.jsonGitHub ↗
{
"client_id": "eco-173-123-456-789",
"hostname": "acme.zayaz.cloud",
"status": "active",
"origin_target": "app_prod",
"primary_region": "eu-north-1",
"data_residency_zone": "eu",
"css_sssr_ref": "sssr:asset.client-profiles.css.css @ eco-173-123-456-789",
"logo_sssr_ref": "sssr:asset.client-profiles.main-logo.gif @ eco-173-123-456-789",
"auth_profile_id": "auth_acme_v1"
}

20.3. DNS Import Strategy (CSV Export)​

Tenant DNS entries can be exported as:

dns-export.csvGitHub ↗
type,name,content,ttl,proxied
CNAME,acme.zayaz.cloud,tenant-edge-router.zayaz.io,300,true

This enables:

  • batch onboarding
  • migration between environments
  • external provisioning systems

20.4. KV Sync Strategy​

KV must be updated:

  • immediately on tenant creation
  • on branding changes
  • on status changes (suspension, activation)

Source of truth:

AWS DB → Event → KV update

21. Authentication & Tenant Context​

Tenant resolution occurs before authentication.


21.1. Flow​

acme.zayaz.cloud
↓
Tenant resolved via KV
↓
Auth system loads tenant-specific config
↓
User authenticates
↓
Session bound to client_id

21.2. Auth Profile Mapping​

auth-profile-mapping.jsonGitHub ↗
{
"auth_profile_id": "auth_acme_v1"
}

Used to determine:

  • SSO provider
  • login method
  • identity domain
  • token configuration

21.3. Key Principle​

Authentication must always be tenant-aware from the first request.


22. Environment Separation​

Each environment must have strict domain isolation.


22.1. Production​

zayaz.cloud
zayaz.io
ecoworld.ai
eco-number.com

22.2. Development​

*.zayaz.dev

Used for:

  • feature branches
  • sandbox tenants
  • test environments

22.3. Rules​

  • No production data on .dev
  • No shared cookies between .dev and .cloud
  • Separate auth systems per environment

23. Future Extensions​

The architecture supports:


23.1. Custom Domains​

app.acme.com → acme.zayaz.cloud

Handled via:

  • Cloudflare custom hostname mapping
  • same KV lookup logic

23.2. Multi-Scope Branding​

Future extension of SSSR:

sssr:asset.client-profiles.css.css @ eco-... + region_id


23.3. Multi-Region Routing​

acme.zayaz.cloud → EU cluster / US cluster

Based on:

  • latency
  • compliance (GDPR, data residency)

23.4. Tenant-Level CDN Overrides​

tenant-specific asset routing via SSSR override_rules


24. Governance & Audit​

All tenant configuration changes must be:

  • logged in ALTD
  • versioned
  • traceable to user/system
  • reversible

24.1. KV Changes​

Every KV write must include:

  • timestamp
  • actor (system/user)
  • diff
  • client_id

24.2. Branding Changes​

Changing:

css_sssr_ref logo_sssr_ref

must:

  • create audit record
  • preserve historical reference
  • support rollback

25. Final Architectural Principle​

The hostname is the entry point. The tenant is the context. The SSSR is the source of truth.

ZAYAZ must never rely on:

  • hardcoded URLs
  • implicit tenant context
  • duplicated branding logic

All runtime behavior must be derived from:

  • hostname
  • KV routing layer
  • SSSR registry
  • control-plane configuration

Final Principle​

Domain architecture = system architecture.

Every domain and subdomain must have a defensible purpose, a clear trust tier, an explicit routing policy, and a governed lifecycle.

ZAYAZ should operate as a global ESG infrastructure layer with production-grade separation between public trust, regulated application runtime, AI surfaces, and partner ecosystems.


APPENDIX A - Tenant Edge Router Spec​

Cloudflare Worker Implementation

A.1. Purpose​

The tenant-edge-router Worker is the runtime ingress for:

  • *.zayaz.cloud
  • future custom hostnames
  • optional tenant-aware login pre-routing

It resolves the incoming hostname to a tenant config, attaches tenant context, enforces status rules, and forwards the request to the correct origin.

Cloudflare recommends wildcard routing to a dispatch Worker for SaaS hostname routing, including subdomains and custom hostnames, and supports KV-backed dynamic mappings. 


A.2. Responsibilities​

The Worker must:

  • read the incoming Host header
  • normalize the hostname
  • resolve tenant config from KV
  • reject unknown / suspended tenants
  • map origin_target to an upstream origin
  • attach tenant context headers
  • preserve request path/query
  • avoid embedding branding values directly
  • return deterministic error pages for inactive tenants
  • emit telemetry for routing outcomes

The Worker must not:

  • be the source of truth for tenant data
  • store large branding payloads
  • execute heavy ESG logic
  • depend on a live AWS lookup on every request

A.3. Inputs​

A.3.1 Incoming request​

Example:

incoming-request.htmlGitHub ↗
GET /login HTTP/1.1
Host: acme.zayaz.cloud

A.3.2 KV key​

acme.zayaz.cloud

A.3.3 KV payload​

kv-payload.jsonGitHub ↗
{
"client_id": "eco-173-123-456-789",
"hostname": "acme.zayaz.cloud",
"status": "active",
"origin_target": "app_prod",
"primary_region": "eu-north-1",
"data_residency_zone": "eu",
"css_sssr_ref": "sssr:asset.client-profiles.css.css @ eco-173-123-456-789",
"logo_sssr_ref": "sssr:asset.client-profiles.main-logo.gif @ eco-173-123-456-789",
"auth_profile_id": "auth_acme_v1"
}

Cloudflare Workers KV supports JSON reads directly through the Worker binding. 


A.4. Origin target model​

origin_target is a ZAYAZ-defined routing alias.

A.4.1 Allowed values​

Examples:

  • app_prod
  • app_maintenance
  • sandbox_default
  • partner_dedicated_acme

A.4.2 Origin map​

Configured in Worker environment or config module:

origin-map.tsGitHub ↗
/**
* Supported regions
*/
type Region = "eu-north-1" | "eu-central-1" | "us-east-1";

/**
* Supported origin targets
*/
type OriginTarget = "app_prod" | "app_maintenance" | "sandbox_default";

/**
* Region → base URL mapping
*/
const REGION_MAP: Record<Region, string> = {
"eu-north-1": "https://eu-north-1.app.zayaz.io",
"eu-central-1": "https://eu-central-1.app.zayaz.io",
"us-east-1": "https://us-east-1.app.zayaz.io",
};

/**
* Resolve origin URL based on target and region
*/
export function resolveOrigin(
originTarget: OriginTarget,
region: Region
): string {
switch (originTarget) {
case "app_prod": {
const url = REGION_MAP[region];
if (!url) {
throw new Error(`Unsupported region: ${region}`);
}
return url;
}

case "app_maintenance":
return "https://maintenance.zayaz.io";

case "sandbox_default":
return "https://sandbox.zayaz.dev";

default:
// Exhaustiveness check (TypeScript safety)
const _exhaustive: never = originTarget;
throw new Error(`Invalid origin_target: ${_exhaustive}`);
}
}

/**
* Example usage
*/
const example = resolveOrigin("app_prod", "eu-north-1");
console.log(example);

A.4.3 Rule​

If origin_target is unknown, return 502 Bad Gateway and emit a routing error event.


A.5. Worker resolution flow​

A.5.1 Happy path​

Request
↓
Extract Host
↓
Normalize hostname
↓
KV lookup by hostname
↓
Validate tenant status
↓
Resolve origin_target → upstream URL
↓
Clone request to upstream
↓
Attach tenant headers
↓
fetch(upstreamRequest)
↓
Return response

A.5.2 Pseudocode​

pseudocode.tsGitHub ↗
/**
* Stand-alone Cloudflare Worker: policy-driven edge routing layer
*/

type TenantStatus = "active" | "inactive" | "suspended" | "maintenance";

type OriginTarget =
| "app_prod"
| "app_maintenance"
| "sandbox_default";

type Region =
| "eu-north-1"
| "eu-central-1"
| "us-east-1";

interface Tenant {
client_id: string;
tenant_slug: string;
hostname: string;
auth_profile_id: string;
css_sssr_ref: string;
logo_sssr_ref: string;
origin_target: OriginTarget;
status: TenantStatus;
primary_region?: Region;
fallback_region?: Region;
}

interface RoutingPolicy {
force_maintenance?: boolean;
allow_fallback_region?: boolean;
default_region?: Region;
}

interface KVNamespaceLike {
get(
key: string,
options?: { type?: "json"; cacheTtl?: number }
): Promise<unknown>;
}

interface Env {
TENANT_ROUTING: KVNamespaceLike;
ROUTING_POLICY?: KVNamespaceLike;
}

const REGION_MAP: Record<Region, string> = {
"eu-north-1": "https://eu-north-1.app.zayaz.io",
"eu-central-1": "https://eu-central-1.app.zayaz.io",
"us-east-1": "https://us-east-1.app.zayaz.io"
};

const STATIC_ORIGINS: Record<Exclude<OriginTarget, "app_prod">, string> = {
app_maintenance: "https://maintenance.zayaz.io",
sandbox_default: "https://sandbox.zayaz.dev"
};

function jsonResponse(body: unknown, status: number): Response {
return new Response(JSON.stringify(body, null, 2), {
status,
headers: {
"content-type": "application/json; charset=utf-8"
}
});
}

function notFoundTenant(hostname: string): Response {
return jsonResponse(
{
ok: false,
error: "tenant_not_found",
hostname
},
404
);
}

function tenantUnavailable(tenant: Tenant): Response {
return jsonResponse(
{
ok: false,
error: "tenant_unavailable",
tenant_slug: tenant.tenant_slug,
status: tenant.status
},
503
);
}

function badOriginTarget(target: string): Response {
return jsonResponse(
{
ok: false,
error: "invalid_origin_target",
origin_target: target
},
502
);
}

function badRegion(region?: string): Response {
return jsonResponse(
{
ok: false,
error: "invalid_region",
region: region ?? null
},
502
);
}

function resolveOrigin(
tenant: Tenant,
policy: RoutingPolicy = {}
): string {
if (policy.force_maintenance || tenant.status === "maintenance") {
return STATIC_ORIGINS.app_maintenance;
}

switch (tenant.origin_target) {
case "app_maintenance":
return STATIC_ORIGINS.app_maintenance;

case "sandbox_default":
return STATIC_ORIGINS.sandbox_default;

case "app_prod": {
const primaryRegion = tenant.primary_region ?? policy.default_region;

if (primaryRegion && REGION_MAP[primaryRegion]) {
return REGION_MAP[primaryRegion];
}

if (
policy.allow_fallback_region &&
tenant.fallback_region &&
REGION_MAP[tenant.fallback_region]
) {
return REGION_MAP[tenant.fallback_region];
}

throw new Error(`No valid region available for tenant "${tenant.tenant_slug}"`);
}

default: {
const exhaustiveCheck: never = tenant.origin_target;
throw new Error(`Unsupported origin target: ${exhaustiveCheck}`);
}
}
}

function buildUpstreamUrl(request: Request, originBase: string): URL {
const upstreamUrl = new URL(request.url);
const origin = new URL(originBase);

upstreamUrl.protocol = origin.protocol;
upstreamUrl.host = origin.host;

return upstreamUrl;
}

function enrichHeaders(headers: Headers, tenant: Tenant, originResolved: string): Headers {
const out = new Headers(headers);

out.set("x-zayaz-client-id", tenant.client_id);
out.set("x-zayaz-tenant-slug", tenant.tenant_slug);
out.set("x-zayaz-hostname", tenant.hostname);
out.set("x-zayaz-auth-profile-id", tenant.auth_profile_id);
out.set("x-zayaz-css-sssr-ref", tenant.css_sssr_ref);
out.set("x-zayaz-logo-sssr-ref", tenant.logo_sssr_ref);
out.set("x-zayaz-origin-target", tenant.origin_target);
out.set("x-zayaz-origin-resolved", originResolved);
out.set("x-zayaz-primary-region", tenant.primary_region ?? "");
out.set("x-zayaz-fallback-region", tenant.fallback_region ?? "");

return out;
}

async function loadRoutingPolicy(env: Env): Promise<RoutingPolicy> {
if (!env.ROUTING_POLICY) {
return {
allow_fallback_region: true,
default_region: "eu-north-1"
};
}

const policy = await env.ROUTING_POLICY.get("global", {
type: "json",
cacheTtl: 60
});

return (policy as RoutingPolicy) ?? {
allow_fallback_region: true,
default_region: "eu-north-1"
};
}

export default {
async fetch(request: Request, env: Env): Promise<Response> {
const url = new URL(request.url);
const hostname = url.hostname.toLowerCase();

const tenant = (await env.TENANT_ROUTING.get(hostname, {
type: "json",
cacheTtl: 60
})) as Tenant | null;

if (!tenant) {
return notFoundTenant(hostname);
}

if (tenant.status === "inactive" || tenant.status === "suspended") {
return tenantUnavailable(tenant);
}

const policy = await loadRoutingPolicy(env);

let originBase: string;
try {
originBase = resolveOrigin(tenant, policy);
} catch (error) {
const message = error instanceof Error ? error.message : String(error);

if (message.includes("region")) {
return badRegion(tenant.primary_region);
}

return badOriginTarget(tenant.origin_target);
}

const upstreamUrl = buildUpstreamUrl(request, originBase);
const upstreamReq = new Request(upstreamUrl.toString(), request);

const routedHeaders = enrichHeaders(
upstreamReq.headers,
tenant,
originBase
);

const routedReq = new Request(upstreamReq, {
headers: routedHeaders
});

const response = await fetch(routedReq);

const outHeaders = new Headers(response.headers);
outHeaders.set("x-zayaz-tenant-routed", "true");
outHeaders.set("x-zayaz-origin-resolved", originBase);

return new Response(response.body, {
status: response.status,
statusText: response.statusText,
headers: outHeaders
});
}
};

The RoutingPolicy can later be extended with fields such as:

force_maintenance?: boolean;
allow_fallback_region?: boolean;
default_region?: Region;
allowed_regions?: Region[];
required_compliance_profile?: string;
origin_failover_mode?: "strict" | "fallback";

This keeps tenant routing facts separate from environment-level routing policy.

  • The tenant record defines tenant-specific routing inputs such as primary_region, fallback_region, origin_target, and status.
  • The routing policy defines global or environment-level rules that influence how those inputs are interpreted.

Over time, resolveOrigin() can evolve into the core decision engine for:

  • maintenance overrides
  • region restrictions
  • failover behavior
  • compliance-aware routing
  • sovereign/data-residency enforcement

Split this further into:

  • tenant-registry.ts
  • routing-policy.ts
  • origin-resolver.ts
  • request-context.ts
  • worker.ts

A.6. Status handling​

A.6.1 active​

Route normally.

A.6.2 provisioning​

Return branded provisioning page or controlled 503.

A.6.3 suspended​

Return branded suspension page or restricted login block.

A.6.4 maintenance​

Route to app_maintenance.

A.6.5 retired​

Return 410 Gone.

Recommended enum:

active
provisioning
maintenance
suspended
retired
error

A.7. Branding behavior​

The Worker does not resolve branding URLs itself unless you deliberately choose to.

It forwards:

  • css_sssr_ref
  • logo_sssr_ref

to the app layer.

Then the app or a resolver API resolves those SSSR references into concrete URLs.

This keeps the Worker:

  • fast
  • deterministic
  • free of asset-resolution complexity

A.8. Authentication behavior​

Tenant resolution happens before login.

A.8.1 Flow​

acme.zayaz.cloud
↓
Worker resolves tenant
↓
Worker forwards auth_profile_id + client_id
↓
App/login service uses tenant-specific auth rules
↓
Session created for client_id

A.8.2 Rule​

No generic login should be shown without tenant context if the request came from a tenant hostname.


A.9. KV update model​

KV should be updated by event-driven sync from the AWS control plane:

  • tenant created
  • hostname changed
  • status changed
  • branding refs changed
  • auth profile changed
  • origin target changed

KV is well-suited for globally replicated routing/config data and read-heavy patterns. 

AWS DB
↓
Control-plane event
↓
KV update API / sync worker
↓
tenant-edge-router reads KV

A.9.2 Safety net​

Run a reconciliation job periodically:

AWS DB ↔ KV ↔ actual routing outcomes


A.10. Cloudflare configuration​

A.10.1 Route​

Use wildcard routing to the Worker.

Cloudflare documents wildcard routing to a dispatch Worker for hostname-based SaaS routing. 

A.10.2 KV binding​

Bind a namespace such as:

kv-binding.tomlGitHub ↗
name = "zayaz-edge-router"
main = "src/index.ts"
compatibility_date = "2026-03-19"

# Enable node compatibility if you use node-style APIs
compatibility_flags = ["nodejs_compat"]

# Default route (production)
routes = [
{ pattern = "*.zayaz.io/*", zone_name = "zayaz.io" }
]

########################################
# KV NAMESPACES (PRODUCTION)
########################################

[[kv_namespaces]]
binding = "TENANT_ROUTING"
id = "prod-tenant-routing-kv-id"

[[kv_namespaces]]
binding = "ROUTING_POLICY"
id = "prod-routing-policy-kv-id"

########################################
# ENV: DEVELOPMENT
########################################

[env.dev]
name = "zayaz-edge-router-dev"

routes = [
{ pattern = "*.dev.zayaz.io/*", zone_name = "zayaz.io" }
]

[[env.dev.kv_namespaces]]
binding = "TENANT_ROUTING"
id = "dev-tenant-routing-kv-id"
preview_id = "dev-tenant-routing-preview-id"

[[env.dev.kv_namespaces]]
binding = "ROUTING_POLICY"
id = "dev-routing-policy-kv-id"
preview_id = "dev-routing-policy-preview-id"

[env.dev.vars]
ENVIRONMENT = "development"
DEFAULT_REGION = "eu-north-1"
ALLOW_FALLBACK = true

########################################
# ENV: STAGING
########################################

[env.staging]
name = "zayaz-edge-router-staging"

routes = [
{ pattern = "*.staging.zayaz.io/*", zone_name = "zayaz.io" }
]

[[env.staging.kv_namespaces]]
binding = "TENANT_ROUTING"
id = "staging-tenant-routing-kv-id"

[[env.staging.kv_namespaces]]
binding = "ROUTING_POLICY"
id = "staging-routing-policy-kv-id"

[env.staging.vars]
ENVIRONMENT = "staging"
DEFAULT_REGION = "eu-central-1"
ALLOW_FALLBACK = true

########################################
# ENV: PRODUCTION (explicit override)
########################################

[env.production]
name = "zayaz-edge-router-prod"

routes = [
{ pattern = "*.zayaz.io/*", zone_name = "zayaz.io" }
]

[[env.production.kv_namespaces]]
binding = "TENANT_ROUTING"
id = "prod-tenant-routing-kv-id"

[[env.production.kv_namespaces]]
binding = "ROUTING_POLICY"
id = "prod-routing-policy-kv-id"

[env.production.vars]
ENVIRONMENT = "production"
DEFAULT_REGION = "eu-north-1"
ALLOW_FALLBACK = true

########################################
# OPTIONAL: R2 (future asset / SSSR storage)
########################################

# [[r2_buckets]]
# binding = "SSSR_ASSETS"
# bucket_name = "zayaz-sssr-assets"

########################################
# OPTIONAL: Durable Objects (future control plane)
########################################

# [[durable_objects.bindings]]
# name = "ROUTING_ENGINE"
# class_name = "RoutingEngine"

########################################
# OPTIONAL: LOGGING / OBSERVABILITY
########################################

[observability]
enabled = true

KV bindings are configured in Wrangler and accessed directly from Worker code. 

A.10.3 Optional custom domains​

Future custom hostnames can be routed through the same dispatch logic. Cloudflare supports hostname routing and custom domains for Workers. 


A.11. Request headers to upstream​

Recommended forwarded headers:

  • x-zayaz-client-id
  • x-zayaz-tenant-slug
  • x-zayaz-hostname
  • x-zayaz-auth-profile-id
  • x-zayaz-css-sssr-ref
  • x-zayaz-logo-sssr-ref

Optional:

  • x-zayaz-origin-target
  • x-zayaz-routing-version
  • x-zayaz-tenant-status

Do not trust these headers from public clients; only trust them when injected by the Worker.


A.12. Error handling​

A.12.1 Unknown hostname​

Response:

  • 404 Not Found
  • internal reason: tenant_not_found

A.12.2 Invalid origin target​

Response:

  • 502 Bad Gateway
  • internal reason: invalid_origin_target

A.12.3 Suspended tenant​

Response:

  • 423 Locked or branded 403/503 depending on UX choice

A.12.4 KV transient failure​

Preferred behavior:

  • attempt fallback control-plane API lookup
  • if resolved, optionally self-heal KV
  • otherwise return controlled 503

A.13. Observability​

Emit structured events for:

  • tenant_route_success
  • tenant_route_not_found
  • tenant_route_suspended
  • tenant_route_invalid_origin
  • tenant_route_kv_miss
  • tenant_route_fallback_api_success
  • tenant_route_fallback_api_failure

Minimum event payload:

minimum-event-payload.jsonGitHub ↗
{
"hostname": "acme.zayaz.cloud",
"client_id": "eco-173-123-456-789",
"tenant_slug": "acme",
"origin_target": "app_prod",
"status": "active",
"outcome": "success",
"timestamp": "2026-03-20T12:00:00Z"
}

A.14. Security rules​

  • do not expose raw AWS control-plane endpoints to the public path
  • never trust client-supplied tenant headers
  • only accept proxied traffic through Cloudflare
  • restrict fallback control-plane API with service auth
  • keep Worker logic minimal and deterministic
  • avoid embedding secrets in KV values

A.15. Future extensions​

The same model supports:

  • custom domains
  • region-aware routing
  • dedicated tenant origins
  • maintenance bypass logic
  • per-tenant feature flags
  • SSSR-driven theme families beyond CSS/logo

A.16. Final rule​

The Worker resolves the hostname. KV provides the routing snapshot. The control plane provides the truth. SSSR provides the branding references.




GitHub RepoRequest for Change (RFC)