feat(cdn): custom domain mapping per organization #563

Open
opened 2026-06-07 15:48:13 +00:00 by jmiller · 2 comments
Owner

Summary

Allow organizations to map custom domains to their CDN endpoints, so release assets are served from branded URLs like cdn.acme.com instead of cdn.mokoconsulting.tech/acme/....

Motivation

Enterprise customers want branded asset delivery URLs for their software distribution. Custom domains are a standard premium feature in CDN products and a natural upsell for commercial licensing.

Feature Scope

Org Settings > CDN > Custom Domains

  • Add/remove custom domains per org (e.g., cdn.acme.com, downloads.acme.com)
  • DNS verification - org admin adds a TXT record to prove domain ownership before activation
  • Auto-TLS via ACME/Let's Encrypt for verified custom domains
  • Domain status dashboard - shows DNS verification state, TLS cert expiry, traffic stats per domain

URL Routing

  • Custom domain requests resolve to the org's repos: cdn.acme.com/:repo/releases/:tag/:filename
  • The owner segment is implied from the domain mapping (no need for /:owner/ in the path)
  • Falls back to 404 if the domain isn't mapped to any org

Database

  • New cdn_custom_domain table:
    • id, org_id, domain, verified (bool), tls_enabled (bool), dns_txt_token (verification token), created_unix, updated_unix
  • SNI-based routing in the CDN handler checks this table for host matching

Access Control

  • Inherits the org-level CDN defaults (IP allowlist, referrer allowlist, rate limits)
  • Per-domain overrides possible (e.g., different IP allowlist per custom domain)
  • Only org owners/admins can manage custom domains

Commercial Licensing

  • Free tier: use the shared cdn.mokoconsulting.tech domain only
  • Paid tier: 1-3 custom domains per org
  • Enterprise tier: unlimited custom domains with auto-TLS

Dependencies

  • Requires #561 (built-in CDN) to be implemented first
  • CDN handler needs to support host-based org resolution in addition to path-based
## Summary Allow organizations to map custom domains to their CDN endpoints, so release assets are served from branded URLs like `cdn.acme.com` instead of `cdn.mokoconsulting.tech/acme/...`. ## Motivation Enterprise customers want branded asset delivery URLs for their software distribution. Custom domains are a standard premium feature in CDN products and a natural upsell for commercial licensing. ## Feature Scope ### Org Settings > CDN > Custom Domains - **Add/remove custom domains** per org (e.g., `cdn.acme.com`, `downloads.acme.com`) - **DNS verification** - org admin adds a TXT record to prove domain ownership before activation - **Auto-TLS** via ACME/Let's Encrypt for verified custom domains - **Domain status dashboard** - shows DNS verification state, TLS cert expiry, traffic stats per domain ### URL Routing - Custom domain requests resolve to the org's repos: `cdn.acme.com/:repo/releases/:tag/:filename` - The owner segment is implied from the domain mapping (no need for `/:owner/` in the path) - Falls back to 404 if the domain isn't mapped to any org ### Database - New `cdn_custom_domain` table: - `id`, `org_id`, `domain`, `verified` (bool), `tls_enabled` (bool), `dns_txt_token` (verification token), `created_unix`, `updated_unix` - SNI-based routing in the CDN handler checks this table for host matching ### Access Control - Inherits the org-level CDN defaults (IP allowlist, referrer allowlist, rate limits) - Per-domain overrides possible (e.g., different IP allowlist per custom domain) - Only org owners/admins can manage custom domains ### Commercial Licensing - Free tier: use the shared `cdn.mokoconsulting.tech` domain only - Paid tier: 1-3 custom domains per org - Enterprise tier: unlimited custom domains with auto-TLS ## Dependencies - Requires #561 (built-in CDN) to be implemented first - CDN handler needs to support host-based org resolution in addition to path-based
Author
Owner

Branch created: feature/563-feat-cdn-custom-domain-mapping-per-organ

git fetch origin
git checkout feature/563-feat-cdn-custom-domain-mapping-per-organ
Branch created: [`feature/563-feat-cdn-custom-domain-mapping-per-organ`](https://code.mokoconsulting.tech/MokoConsulting/MokoGitea/src/branch/feature/563-feat-cdn-custom-domain-mapping-per-organ) ```bash git fetch origin git checkout feature/563-feat-cdn-custom-domain-mapping-per-organ ```
Author
Owner

Clarification: Custom Domain = White-Label Org Portal

This is bigger than just CDN. When a custom domain CNAME is pointed at the MokoGitea instance:

Scoped UI

  • MokoGitea detects the custom domain via the Host header
  • The UI only shows that org's repos, releases, and content - no other orgs or users visible
  • Navigation, explore pages, and search are all scoped to the mapped org
  • Effectively a white-labeled, single-tenant view of a multi-tenant MokoGitea instance

Custom Branding

  • The login page displays the org's chosen company logo/image instead of the default MokoGitea branding
  • Site title, favicon, and colors could also be org-customizable
  • Needs new org settings fields: custom_logo, custom_favicon, custom_site_title, brand_color

How It Works

  1. Org admin adds git.acme.com as a custom domain in org settings
  2. Org admin creates a CNAME: git.acme.com -> git.mokoconsulting.tech
  3. MokoGitea verifies the CNAME via DNS TXT record
  4. Once verified, any request to git.acme.com loads MokoGitea scoped to that org with their branding
  5. CDN assets also work: git.acme.com/:repo/releases/:tag/:filename

This makes MokoGitea a true multi-tenant SaaS platform

  • Each paying org gets their own branded URL
  • Users only see their org's content
  • The underlying instance is shared (lower infra cost)
  • Premium feature for enterprise licensing tier
## Clarification: Custom Domain = White-Label Org Portal This is bigger than just CDN. When a custom domain CNAME is pointed at the MokoGitea instance: ### Scoped UI - MokoGitea detects the custom domain via the `Host` header - The UI **only shows that org's repos, releases, and content** - no other orgs or users visible - Navigation, explore pages, and search are all scoped to the mapped org - Effectively a white-labeled, single-tenant view of a multi-tenant MokoGitea instance ### Custom Branding - The **login page** displays the org's chosen company logo/image instead of the default MokoGitea branding - Site title, favicon, and colors could also be org-customizable - Needs new org settings fields: `custom_logo`, `custom_favicon`, `custom_site_title`, `brand_color` ### How It Works 1. Org admin adds `git.acme.com` as a custom domain in org settings 2. Org admin creates a CNAME: `git.acme.com -> git.mokoconsulting.tech` 3. MokoGitea verifies the CNAME via DNS TXT record 4. Once verified, any request to `git.acme.com` loads MokoGitea scoped to that org with their branding 5. CDN assets also work: `git.acme.com/:repo/releases/:tag/:filename` ### This makes MokoGitea a true multi-tenant SaaS platform - Each paying org gets their own branded URL - Users only see their org's content - The underlying instance is shared (lower infra cost) - Premium feature for enterprise licensing tier
Sign in to join this conversation.