WEB / WEB-06.02
Domain, site, and origin
Distinguish hostname, registrable domain, schemeful site, and origin for the same URL pair; separate browser boundaries from application permission.
1. Core · Mechanism
Read every scenario without motion
Subdomain
- Pair selected
The base https://app.example.com/catalog will be compared with https://api.example.com/catalog. The URL pair is ready; origin and site results are not yet computed.
- URL pair
- https://api.example.com/catalog
- Boundary calculation
- Origins: pending
- Result ledger
- Result: pending
- Origin tuples are separated
The changed tuple component is hostname app.example.com → api.example.com. This HTTP(S) origin comparison gives same-origin=false; retaining path /catalog does not remove the changed component.
- URL pair
- https://api.example.com/catalog
- Boundary calculation
- Origin: https://api.example.com
- Result ledger
- Same-origin: false
- Site is computed separately
The selected-domain fixture uses scheme and registrable domain, excluding port.
- URL pair
- https://api.example.com/catalog
- Boundary calculation
- Site: https://example.com
- Result ledger
- Same-site: true
- Both results are retained
Classification is not access permission or network success.
- URL pair
- https://api.example.com/catalog
- Boundary calculation
- Local calculation complete
- Result ledger
- Same-origin: false; same-site: true
Port 8443
- Pair selected
The base https://app.example.com/catalog will be compared with https://app.example.com:8443/catalog. The URL pair is ready; origin and site results are not yet computed.
- URL pair
- https://app.example.com:8443/catalog
- Boundary calculation
- Origins: pending
- Result ledger
- Result: pending
- Origin tuples are separated
The changed tuple component is effective port 443 → 8443. This HTTP(S) origin comparison gives same-origin=false; retaining path /catalog does not remove the changed component.
- URL pair
- https://app.example.com:8443/catalog
- Boundary calculation
- Origin: https://app.example.com:8443
- Result ledger
- Same-origin: false
- Site is computed separately
The selected-domain fixture uses scheme and registrable domain, excluding port.
- URL pair
- https://app.example.com:8443/catalog
- Boundary calculation
- Site: https://example.com
- Result ledger
- Same-site: true
- Both results are retained
Classification is not access permission or network success.
- URL pair
- https://app.example.com:8443/catalog
- Boundary calculation
- Local calculation complete
- Result ledger
- Same-origin: false; same-site: true
HTTP scheme
- Pair selected
The base https://app.example.com/catalog will be compared with http://app.example.com/catalog. The URL pair is ready; origin and site results are not yet computed.
- URL pair
- http://app.example.com/catalog
- Boundary calculation
- Origins: pending
- Result ledger
- Result: pending
- Origin tuples are separated
The changed tuple component is scheme https → http. This HTTP(S) origin comparison gives same-origin=false; retaining path /catalog does not remove the changed component.
- URL pair
- http://app.example.com/catalog
- Boundary calculation
- Origin: http://app.example.com
- Result ledger
- Same-origin: false
- Site is computed separately
The selected-domain fixture uses scheme and registrable domain, excluding port.
- URL pair
- http://app.example.com/catalog
- Boundary calculation
- Site: http://example.com
- Result ledger
- Same-site: false
- Both results are retained
Classification is not access permission or network success.
- URL pair
- http://app.example.com/catalog
- Boundary calculation
- Local calculation complete
- Result ledger
- Same-origin: false; same-site: false
Opaque identities
- Two supplied identities
opaque-A and opaque-B are distinct fixture identities.
- URL pair
- opaque-A / opaque-B
- Boundary calculation
- Comparison: pending
- Result ledger
- Result: pending
- Serialization looks equal
Two distinct opaque identities serialize as the same null text; the text does not establish identity equality.
- URL pair
- Distinct identities
- Boundary calculation
- null / null
- Result ledger
- Identity verdict: pending
- Identity rule is applied
Distinct opaque identities are not same-origin; text equality is insufficient.
- URL pair
- opaque-A ≠ opaque-B
- Boundary calculation
- Identity equality: false
- Result ledger
- Same-origin: false
- Model scope is recorded
This supplied-fixture example created no browser Documents.
- URL pair
- Fixture only
- Boundary calculation
- Internal identities supplied
- Result ledger
- Browser enforcement: not run
ACTORS · STATE · DATA FLOW
Distinguish the hostname from domain boundaries
The hostname of https://app.example.com/catalog is app.example.com. Labels belong to DNS name structure, but the word domain alone does not specify a boundary. Distinguish a full hostname, a public suffix, and a registrable domain when reviewing configuration.
Public suffixes define registration boundaries and can have different lengths, such as com and co.uk. A registrable domain adds the appropriate preceding label. Consequently, taking the final two labels does not work universally. The Public Suffix List supplies boundary data, not proof of domain ownership.
The artifact uses selected ordinary names below example.com and example.org. com/org and the two registrable domains are explicit fixture inputs. It does not reimplement the complete PSL, IDNA, IP handling, or every host form.
Origin identifies a scheme/host/port boundary
For ordinary HTTP(S) URLs, origin comparison uses scheme, host, and normalized port. https://app.example.com/catalog and https://app.example.com/notes?lang=en#new have the same origin: path, query, and fragment do not alter this boundary.
https://api.example.com changes the host; https://app.example.com:8443 changes a non-default port; http://app.example.com changes the scheme. Each differs from the original default-port HTTPS origin, even when one team operates them all.
Normalization matters: https://app.example.com:443 serializes to origin https://app.example.com. URL.origin supplies comparable serializations for these HTTP(S) examples. Origin equality does not require identical raw address strings.
A schemeful site is a broader boundary
For these HTTP(S) domain examples, a schemeful site combines the scheme with the registrable domain. https://app.example.com and https://api.example.com share site https://example.com. Different hosts make them cross-origin while the HTTPS registrable domain makes them same-site.
Ports are excluded from site comparison. https://app.example.com:8443 is cross-origin but same-site relative to the default-port origin. Changing the scheme changes the schemeful site: http://app.example.com is cross-site in this example.
This explanation concerns domain examples. The standard also has host fallback when no registrable domain exists and rules for opaque origins. The selected-domain fixture is not a universal site API for every address type.
Same-site does not grant same-origin authority
Origin is a fundamental browser isolation boundary; site is a different grouping used, for example, in SameSite cookie evaluation. Same-site applications do not thereby receive unrestricted access to each other’s DOM or response bodies. Identify the specific operation and browser policy.
SOP, CORS, and cookie transmission are developed in their own lessons. This table only classifies same-origin and same-site. Cross-origin does not mean all communication is forbidden or that a server certainly never receives a request.
Server authentication and resource authorization remain independent. Before giving Duru an Atlas report, even a same-site API must evaluate principal, tenant, action, and object relationships. A browser boundary does not prove ownership.
Do not reduce an opaque origin to the string null
Origins are not all HTTP(S) tuples. An opaque origin has an internal identity and can serialize as null. Two distinct opaque origins producing the same null string does not establish internal origin equality.
The artifact declares opaque-A and opaque-B as separate identity fixtures: both serialize as null, while identity equality is false. They are explanatory aliases, not actual browser Document origins.
Do not design a policy that treats serialized null as a trusted origin name. The embedding, sandbox, or document context that created the identity matters. This lesson creates no browser sandbox and relaxes no boundary.
2. Red · Trust & Impact
Read every scenario without motion
Site / origin
- The trust question selected the right identity
The base is https://app.example.com/catalog and api.example.com is the subdomain case. Same-site family membership does not produce one origin tuple.
- Identity evidence
- app vs api / shared site
- Boundary comparison
- No boundary comparison
- Access conclusion
- No access claim
- Comparison retained information lost in text
The API host has origin https://api.example.com and site https://example.com. It is not same-origin with the base URL but is same-site. Those results answer different boundary questions.
- Identity evidence
- app vs api / shared site
- Boundary comparison
- Origin false / site true
- Access conclusion
- No access claim
- No application-access outcome was added
Boundary classification is neither an actual browser read-policy nor server-authorization outcome. BrowserEnforcementExecuted=false leaves response readability and user entitlement unknown.
- Identity evidence
- app vs api / shared site
- Boundary comparison
- Origin false / site true
- Access conclusion
- UNKNOWN: actual access
- Port and scheme are separate causes
Port 8443 changes the origin but not the site. HTTP changes both origin and schemeful site; reporting a Boolean pair without its changed component is insufficient.
- Identity evidence
- Host / port / scheme causes separate
- Boundary comparison
- Origin false / site true
- Access conclusion
- UNKNOWN: actual access
- The site fixture is not a universal PSL
fixtureRegistrableDomains defines only app/api.example.com and app.example.org examples. A last-two-label shortcut is not expanded to all suffixes or localhost/IP/opaque contexts.
- Identity evidence
- Host / port / scheme causes separate
- Boundary comparison
- Selected domain map / no universal shortcut
- Access conclusion
- UNKNOWN: actual access
- The control preserved the required boundary
A same-origin requirement retains the complete scheme/host/normalizedPort tuple. Same-site cookie and server-entitlement controls are not substituted for it.
- Identity evidence
- Host / port / scheme causes separate
- Boundary comparison
- Selected domain map / no universal shortcut
- Access conclusion
- Tuple boundary preserved / access unknown
Opaque identity
- The trust question selected the right identity
opaqueComparison provides distinct aliases opaque-A and opaque-B, both serialized as null. Equal text does not mean equal origin identity.
- Identity evidence
- opaque-A ≠ opaque-B / both null
- Boundary comparison
- No boundary comparison
- Access conclusion
- No access claim
- Comparison retained information lost in text
sameOriginIdentity=false is supplied. Serialization comparison loses opaque context type and identity distinction; these aliases do not create actual Document origins.
- Identity evidence
- opaque-A ≠ opaque-B / both null
- Boundary comparison
- Identity false / serialization equality insufficient
- Access conclusion
- No access claim
- No application-access outcome was added
Boundary classification is neither an actual browser read-policy nor server-authorization outcome. BrowserEnforcementExecuted=false leaves response readability and user entitlement unknown.
- Identity evidence
- opaque-A ≠ opaque-B / both null
- Boundary comparison
- Identity false / serialization equality insufficient
- Access conclusion
- UNKNOWN: actual access
- Null serialization carries no identity
opaque-A and opaque-B serialize to the same null text but are distinct identities in the example. Host/port tuple comparison does not apply to these opaque values. Their internal identity distinction cannot be recovered through text equality.
- Identity evidence
- opaque-A ≠ opaque-B; text null / null
- Boundary comparison
- Identity false / serialization equality insufficient
- Access conclusion
- UNKNOWN: actual access
- The origin-producing context matters
In an actual browser review, the Document and embedding/sandbox context establish the origin identity. This alias example creates no Document and treats null text as neither a trusted origin nor an access allowance. Without observing the producing context, that relationship is unknown.
- Identity evidence
- opaque-A ≠ opaque-B; text null / null
- Boundary comparison
- Alias identity supplied; no actual Document
- Access conclusion
- UNKNOWN: actual access
- The control preserved the required boundary
Opaque-identity distinction is retained outside serialization. Actual Document/sandbox context and enforcement require separate evidence; null-text equality grants no allowance.
- Identity evidence
- opaque-A ≠ opaque-B; text null / null
- Boundary comparison
- Alias identity supplied; no actual Document
- Access conclusion
- Opaque identity separate / enforcement unknown
ASSUMPTION · BOUNDARY · CONTROL
Ask which boundary the comparison measures
A shared domain family is insufficient for a technical conclusion. App and API hosts can be same-site but cross-origin; a port change also separates origins. Present the address pair, normalized origins, and site result together.
In the artifact’s API-host branch, parsing produces different origins while the selected PSL fixture produces one site. Substituting the latter for the former misreads the browser trust boundary.
The subdomain and port cases share the false/true pair: cross-origin but same-site. One differs in host, the other in port. Rather than reporting booleans alone, name the changed tuple component so a reviewer can see what the relevant control must preserve.
Separate classification from observed access
Do not infer server responses or user authorization from the origin table. This lesson computes URL tuples without measuring browser read policy, an actual request, or authorization.
The opaque branch demonstrates identities that serialization cannot distinguish. A text-equality audit can be insufficient; preserve the origin type and context as well.
The opaque fixture explicitly supplies distinct identity aliases, but null text carries no such distinction. It cannot tell which identity a browser assigned to a particular iframe. That broader question requires actual Document/sandbox context; the artifact explains a rule without pretending to measure an uncreated browser context.
3. Blue · Secure development & defense
Read every scenario without motion
Domain map
- Base origin and site have separate columns
baseOrigin=https://app.example.com and baseSite=https://example.com. Path/query/fragment changes stay same-origin; site grouping does not authorize a consumer.
- URL matrix evidence
- Base origin / base site separate
- Tuple/domain calculation
- No tuple review
- Change review
- No coverage conclusion
- Normalized-port baseline was calculated
Normalizing explicit port 443 retains origin https://app.example.com. Port 8443 instead gives https://app.example.com:8443 while retaining the site group. Raw URL equality differs from origin-tuple equality.
- URL matrix evidence
- Base origin / base site separate
- Tuple/domain calculation
- 443 normalized / 8443 cross-origin
- Change review
- No coverage conclusion
- Host-map scope remained explicit
app and api.example.com map to example.com; app.example.org maps to example.org. This selected map does not compute results for unlisted hosts.
- URL matrix evidence
- com/org fixture map only
- Tuple/domain calculation
- 443 normalized / 8443 cross-origin
- Change review
- No coverage conclusion
- The scheme negative control was preserved
HTTP app.example.com has origin=http://app.example.com and site=http://example.com. Its schemeful site differs from HTTPS; this changes a different component from the port rule.
- URL matrix evidence
- com/org fixture map only
- Tuple/domain calculation
- HTTP vs HTTPS / both scopes differ
- Change review
- No coverage conclusion
- Observation type remained explicit
Native URL origin calculation, selected-map site calculation and actual browser enforcement are separate evidence kinds. Without enforcement, no CORS/read-policy or resource allowance is added.
- URL matrix evidence
- com/org fixture map only
- Tuple/domain calculation
- HTTP vs HTTPS / both scopes differ
- Change review
- Parser / fixture / enforcement separate
- Change review followed the actual requirement
Same-host/default-port, subdomain, port, scheme and other-site controls remain together. Not-computed for unknown contexts is more accurate than an unsupported PSL generalization.
- URL matrix evidence
- com/org fixture map only
- Tuple/domain calculation
- HTTP vs HTTPS / both scopes differ
- Change review
- Scoped matrix consistent / unknown retained
Port change
- Two ports on the same host were selected
The base is https://app.example.com/catalog and the comparison is https://app.example.com:8443/catalog. Scheme and hostname match while effective ports differ. No access or network outcome exists yet.
- URL matrix evidence
- app.example.com; HTTPS; 443 / 8443
- Tuple/domain calculation
- Tuple comparison pending
- Change review
- Access unobserved
- The port separates origin tuples
The URL API produces https://app.example.com and https://app.example.com:8443. HTTPS default port 443 normalizes away; non-default 8443 remains. This pair gives sameOrigin=false.
- URL matrix evidence
- Default 443 / explicit 8443
- Tuple/domain calculation
- Same-origin false; different port
- Change review
- Access unobserved
- Site calculation excludes the port
The supplied domain map maps app.example.com to example.com. Both URLs use https, so their site is https://example.com and sameSite remains true. This site equality does not erase the origin difference.
- URL matrix evidence
- https + example.com matches for both URLs
- Tuple/domain calculation
- Same-origin false / same-site true
- Change review
- Access unobserved
- A scheme change belongs to another row
The separate http://app.example.com/catalog row changes both origin and schemeful site. In port-change, the scheme remains HTTPS and same-site stays true. Do not copy the HTTP row’s false site result into this port comparison.
- URL matrix evidence
- Port pair remains HTTPS
- Tuple/domain calculation
- Port pair: false / true; scheme row separate
- Change review
- Access unobserved
- A calculation producer is not an enforcement producer
Origin output comes from the native URL API; site output comes only from the supplied registrable-domain map. Browser response-read policy and server resource policy are separate operations that may consume these values; neither runs here.
- URL matrix evidence
- URL pair and outputs retained together
- Tuple/domain calculation
- Origin API / site fixture / enforcement separate
- Change review
- Coverage limited to calculation; no allowance
- The consumer contract must evaluate the new origin
Moving the API’s own port to 8443 changes the API origin, not automatically the consuming Document’s origin. Review the consumer/API relationship and CORS requirements separately. Remaining same-site does not prove the earlier permission contract still applies.
- URL matrix evidence
- API origin changed; consumer separate
- Tuple/domain calculation
- Same-origin false / same-site true
- Change review
- Classification known; app policy separate
IMPLEMENTATION · SECURITY CONTROL · VERIFICATION
Define origin policy with the complete tuple
An ordinary HTTP(S) origin policy evaluates the full scheme, host, and normalized port tuple. Checking only a registrable domain does not satisfy a same-origin requirement; changing a path alone does not change the origin.
When adding a subdomain or port, review cookie, CORS, and server authorization contracts independently. A same-site classification does not automatically validate other controls.
Moving an API from port 443 to 8443 creates a new origin while it can remain same-site. Review permitted browser consumers using origin tuples and user/resource permissions using server policy. A single domain-trusted verdict cannot replace these two decisions; neither supplies the other’s evidence.
Record PSL and exceptional-origin context
For production site calculations, use platform or library behavior with appropriate current PSL data. Do not generalize a final-two-label shortcut from this limited example fixture. IPs, localhost, and opaque contexts need their own rules.
Include pairs for normalized default ports, different ports, subdomains, schemes, and sites in regression observations. Label native parser results, selected-fixture calculations, and actual browser enforcement distinctly.
Keep expectedOrigin and expectedSite as separate columns for the six ordinary URL pairs. The selected domain fixture must not produce a guessed site for an unlisted host. An unknown/not-computed observation for an unsupported context is more accurate evidence than a falsely universal PSL calculation.
NOW APPLY IT TO THE CASE
How are tuples, registrable domains and opaque identities kept separate?
app and api.example.com are same-site but cross-origin. Using port 8443 changes the origin. opaque-A and opaque-B remain distinct supplied identities even though both serialize to null.
Identify the case’s browser and API through URL components. Target, origin and site answer different questions; identify which decision uses each one.
Open the related case file ↗READ THE EXAMPLE TOGETHER
Origin / schemeful-site comparison matrix
Select a field and examine what it supports and where the evidence ends.
Read the raw artifact and field explanations
{
"base": "https://app.example.com/catalog",
"baseOrigin": "https://app.example.com",
"baseSite": "https://example.com",
"fixtureRegistrableDomains": {
"app.example.com": "example.com",
"api.example.com": "example.com",
"app.example.org": "example.org"
},
"cases": [
{
"case": "same-origin",
"url": "https://app.example.com/notes?lang=en#new",
"expectedOrigin": "https://app.example.com",
"expectedSite": "https://example.com",
"sameOrigin": true,
"sameSite": true
},
{
"case": "default-port",
"url": "https://app.example.com:443/catalog",
"expectedOrigin": "https://app.example.com",
"expectedSite": "https://example.com",
"sameOrigin": true,
"sameSite": true
},
{
"case": "subdomain",
"url": "https://api.example.com/catalog",
"expectedOrigin": "https://api.example.com",
"expectedSite": "https://example.com",
"sameOrigin": false,
"sameSite": true
},
{
"case": "port",
"url": "https://app.example.com:8443/catalog",
"expectedOrigin": "https://app.example.com:8443",
"expectedSite": "https://example.com",
"sameOrigin": false,
"sameSite": true
},
{
"case": "scheme",
"url": "http://app.example.com/catalog",
"expectedOrigin": "http://app.example.com",
"expectedSite": "http://example.com",
"sameOrigin": false,
"sameSite": false
},
{
"case": "other-site",
"url": "https://app.example.org/catalog",
"expectedOrigin": "https://app.example.org",
"expectedSite": "https://example.org",
"sameOrigin": false,
"sameSite": false
}
],
"opaqueComparison": {
"leftIdentity": "opaque-A",
"rightIdentity": "opaque-B",
"leftSerialization": "null",
"rightSerialization": "null",
"sameOriginIdentity": false,
"scope": "Supplied distinct identities, not actual browser Document origin objects"
},
"pslScope": "Explicit selected com/org examples only; not a complete PSL implementation",
"browserEnforcementExecuted": false
}- baseOrigin / baseSite
- Two different boundaries for the base address.
- cases.sameOrigin
- Equality of normalized HTTP(S) tuples.
- cases.sameSite
- Schemeful-site equality using an explicit registrable-domain fixture.
- opaqueComparison
- Equal serialization with distinct supplied identities; no browser enforcement.
URL.origin is computed with the native Node API. Site uses the declared fixture domain map; no complete PSL, Document origins, SOP/CORS/cookies, or network executes.
Two reality checks
Same-site applications share same-origin authority.
Subdomains or ports can separate origins. Site classification is not DOM/read permission or object authorization.
Origins serialized as the same null text are equal.
Opaque identities cannot be reconstructed from serialization; distinct identities can share the same text.
YOUR TURN
Work through this story.
Predict the outcome, find the evidence boundary, and explain it in your own words.
Does https://app.example.com:443 share the base origin?
- Yes; HTTPS default port 443 is the same effective port.
- No; a visible :443 always changes the origin.
Read the explained answer
Yes; HTTPS default port 443 is the same effective port. — Explicit :443 is normalized in the default-port branch; path/query/fragment are not part of the origin tuple.
Two opaque origins serialize as null. Can they be inferred to share an origin?
Selected lesson artifact fields; teaching example
- opaqueComparison
- {"leftIdentity":"opaque-A","rightIdentity":"opaque-B","leftSerialization":"null","rightSerialization":"null","sameOriginIdentity":false,"scope":"Supplied distinct identities, not actual browser Document origin objects"}
- No; supplied opaque-A and opaque-B are distinct identities.
- Yes; equal null strings imply equal identities.
Read the explained answer
No; supplied opaque-A and opaque-B are distinct identities. — Serialization is not a unique identity token; sameOriginIdentity=false is supplied explicitly.
api.example.com is same-site but cross-origin. Why does that distinction not grant a sibling app script-read permission?
Read the explained answer
The selected schemeful site matches through the registrable domain; differing hostnames make the origins distinct. Same-site grouping neither removes SOP nor proves a sibling owner trustworthy. This fixture uses only selected com/org PSL examples and executes no browser enforcement.
□ I separated same-site from same-origin.
□ I inferred no read permission from grouping.
Open the application console · request / response / browser
Also open request, URL, cookie and DOM examples
MANUAL LAB
URL Boundary Lab
Predict components, origin/site comparisons, and relative resolution before comparing native API output.
Open the prediction → observation → explanation workbook ↗Source on GitHub ↗Sources and scope
- WHATWG HTML — Origins and sites7.1.1 Origins: tuple/opaque; serialization; same origin · 7.1.1.1 Sites: obtain a site; same site
- WHATWG — URL StandardGoals · 4.1 URLs · 4.2 URL miscellaneous: default port · 4.4 URL parsing · 4.7 Origin · 6.1 URL class
- MDN — SiteDescription: registrable domain; schemeful site; origin comparison
- MDN — OriginScheme, hostname, and port definition
- Public Suffix List — LearnWhat is a public suffix?; registrable domains and cookie boundaries