Blinkin URL Migration Findings
Situation
The current rehearsal surface is app-upco.blinkin.de. It can authenticate
into the restored Blinkin tenant and show restored production data. The problem appears
when opening a companion: generated links still point to blinkin.blinkin.io.
This is expected from the restored data model: published companion/app links use
tenant.domain as the canonical public host.
Confirmed Root Cause
domain: blinkin.blinkin.io. That value drives companion URL
generation and sends users back to the old AWS-backed host.
{
"id": 126,
"name": "Blinkin",
"domain": "blinkin.blinkin.io",
"auth0Id": "org_O7TERzIkkx3IMBw8"
}
Inventory Snapshot
| ID | Tenant | Current Domain | Rehearsal Status |
|---|---|---|---|
| 126 | Blinkin | blinkin.blinkin.io | Map to app-upco.blinkin.de for candidate rehearsal. |
| 133 | Wilo SE | wilo.blinkin.io | Needs explicit DNS, proxy, and Auth0 decision. |
| 175 | Fraunhofer | fraunhofer.blinkin.io | Needs explicit DNS, proxy, and Auth0 decision. |
| 217 | Telekom | telekom.blinkin.io | Needs explicit DNS, proxy, and Auth0 decision. |
| 220 | TAPGIG | tapgig.blinkin.io | Needs explicit DNS, proxy, and Auth0 decision. |
| 221 | Fortinet | fortinet.blinkin.io | Needs explicit DNS, proxy, and Auth0 decision. |
| 225 | Bosch Industriekessel | bosch.blinkin.io | Needs explicit DNS, proxy, and Auth0 decision. |
| 231 | Acme | demo.blinkin.io | Needs explicit DNS, proxy, and Auth0 decision. |
| 232 | Huber & Ranner | huberranner.blinkin.io | Needs explicit DNS, proxy, and Auth0 decision. |
| 341 | Gebr Heinemann | heinemann.blinkin.io | Needs explicit DNS, proxy, and Auth0 decision. |
| 345 | Peri | peri.blinkin.io | Needs explicit DNS, proxy, and Auth0 decision. |
| 347 | muehlhausmoers | emmy.blinkin.io | Needs explicit DNS, proxy, and Auth0 decision. |
Live Boundary Checks
app-upco.blinkin.de -> 178.105.30.180
app-prod.blinkin.de -> 178.105.98.166
blinkin.blinkin.io -> AWS NLB / 63.178.127.147, 3.126.66.33, 18.199.229.247
telekom.blinkin.io -> AWS NLB / 63.178.127.147, 18.199.229.247, 3.126.66.33
https://app-upco.blinkin.de/__healthz -> 200 text/plain
https://app-upco.blinkin.de/houston/tenants/current -> 200 application/json
https://blinkin.blinkin.io/houston/tenants/current -> 200 text/html
GitHub Runbook Cross-Check
The exact runbook is now available as the authoritative checklist:
Tenant Subdomains and Public Media Asset Fix Runbook. Initial
GitHub checkout/search did not locate it by title, but the supplied text
has been preserved in the repo evidence set and reconciled against the
app-upco findings.
| Found Doc | What It Proves | Limit |
|---|---|---|
2026-05-09T19-14-55Z-apps-auth0-and-studio-media-fix.md |
Staging Auth0 callback and Studio media base were fixed for *.blinkin.de. |
It explicitly did not touch blinkin.io production Auth0, DNS, or runtime files. |
2026-05-10-prod-clean-rebuild-runbook.md |
Prod rebuild must keep prod-only DB, storage, Auth0, domains, and secrets separate. | DNS/Auth0 cutover is a separate approval gate, not part of the rebuild itself. |
2026-05-10-staging-url-architecture.md |
Tenant hosts such as acme.blinkin.de represent real org/Auth0/tenant identity. |
The doc treats .de as safe staging/rebuild and .io as current production shape. |
.de Hetzner production/candidate surface: public tenant hosts become
<tenant>.blinkin.de, stale .blinkin.io generated links are
eliminated, and media is resolved through the Azure account root. If the
final business goal is to keep customer-facing .io, do not blindly
apply the .io -> .de tenant-domain migration as the final cutover.
Move DNS/proxy/Auth0 behind the .io hosts instead.
Runbook Checklist Added
The preserved checklist adds a second risk class to this migration: public media. The media fix is separate from tenant-domain canonicalization.
| Risk | Required Rule | Verification |
|---|---|---|
| Tenant URLs | For the .de clone, generated companion URLs must use the selected canonical suffix. |
SQL has zero %.blinkin.io rows; copied/opened companion URLs do not contain .blinkin.io. |
| Staging wildcard | Prefer <tenant>.staging.blinkin.de unless Cloudflare routes <tenant>.blinkin.de to staging. |
dig and curl -I hit the intended staging VM, not production. |
| Media base | Use https://picassoprod.blob.core.windows.net, not a value ending in /images. |
No public JSON or HTML contains /images/images/ or root-relative uploaded media paths. |
Immediate Safe Fix For Rehearsal
Candidate-only dry-run SQL for the Blinkin tenant:
BEGIN;
UPDATE tenant
SET domain = 'app-upco.blinkin.de'
WHERE id = 126
AND domain = 'blinkin.blinkin.io';
SELECT id, name, domain, auth0_id
FROM tenant
WHERE id = 126;
-- ROLLBACK; -- keep this while reviewing
-- COMMIT; -- only after human approval and companion-link verification
Do Not Bulk-Map Enterprises Yet
telekom.blinkin.io to
telekom.blinkin.de without routing proof can break enterprise login and
public companion access.
- DNS must exist and point to the intended Hetzner candidate or proxy.
- Caddy/reverse proxy must accept that host and route app/API traffic correctly.
- Auth0 callback, logout, and web origin settings must allow that host.
Final .io Cutover Model
If the final goal is to keep customer-facing .io domains, the cutover is
mainly DNS/proxy/Auth0 plus final sync, not a blind tenant-domain rewrite.
- Move
.ioDNS from AWS to Hetzner. - Configure Hetzner Caddy/proxy for every
.iohost. - Confirm Auth0 production settings for callbacks, logout URLs, and web origins.
- Freeze old production and perform one final database/media sync.