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)