Setting an endpoint's scope to Public puts it on the internet under a name of its own, with a certificate, and with no proxy in the path.

On ORC8R Cloud everything a public name needs — the public base domain, the DNS records, the addresses your pools answer on, and the certificate — is managed for you. There is no zone DNS setup, no address plan to declare, and no Cloudflare token or ACME account to configure. Exposing a service is a single control in the request composer, and the platform does the rest.

Exposing a service

The exposure itself is one control per endpoint.

  1. Open the request composer and add the app to the pool as usual.
  2. In the app's Exposure section, find the row for the endpoint you want on the internet.
  3. Set that row's scope to Public.
  4. Optionally set a Service name. It defaults to the pool's name, and it is the label that ends up in DNS.
  5. Submit the request.

The same thing in the request document:

apps:
  - name: postgres
    endpoints:
      pg:
        expose: public
        name: maindb

On submission the pool draws a public address, the platform publishes the record, and — for a service that terminates TLS — a certificate is ordered. The address behind a live service never moves because you edited its request: a later reconfiguration only fills in a family the pool is missing.

Service names

Service names must be unique among your organization's active public exposures. A collision is refused when you submit, and the error names the pool holding the name. Because the name is request configuration rather than topology, it survives a pool rename and follows the service if you move it to a different pool — the new request simply carries the same name. A released name rests in quarantine for a while before another project can take it, so that stale bookmarks cannot land on a stranger; the project that released it can re-claim it immediately, which is what makes moving a service possible.

A public name resolves to one pool address, never to node addresses. One machine at a time receives that address's traffic and forwards each flow to a node; when it fails, the platform moves the responsibility within seconds and the DNS record never changes. Your app sees the real client address, not a proxy's.

What the platform handles for you

  • The public base domain. An exposed service is {service}.{org}.{base} — storefront in organization acme is published under the zone's managed base domain. You do not delegate a domain or hold a DNS token.
  • The records. For a service named storefront serving an endpoint on port 8080, an AAAA/A record for the pool address is published and health-fed: it withdraws while no node can serve the port and returns when one can. The ACME challenge record is published and retracted around each certificate order. You add nothing by hand.
  • The addresses. Each exposed pool draws a public address per family automatically; there is no plan to declare and no routed-host list to maintain.

Because the name answers the pool address or no address at all, a pool with nothing healthy behind a primary endpoint refuses the connection rather than serving it from a node the app has not vouched for — the name keeps resolving, the port just has nothing to offer yet.

Certificates

Public TLS is one certificate per publicly exposed service, carrying that service's public name — storefront.acme.example.com — and nothing else. No wildcard is ever issued, and the platform orders, installs, and renews it for you. A certificate is ordered only when the exposure actually needs one, which means the app terminates TLS on it: the endpoint declares its protocol as https, or the app binds tls.cert with purpose: server_tls. A service published over plain tcp or udp that asks for neither gets no certificate, and its name never reaches a certificate authority at all.

The certificate and its private key reach the nodes of the pool that exposes the service through the tls.cert and tls.key parameters, and reach no other pool. The key a node holds proves exactly the one name that node serves, so a node someone takes over can impersonate nothing else of yours.

Direct delivery is app-terminated — on a pool whose public endpoints are delivered directly on a pool address, there is no platform proxy to terminate TLS for you, so a publicly exposed web endpoint must speak HTTPS itself: declare its protocol as https and serve TLS with the delivered certificate (see Authoring apps). There a plaintext http endpoint is rejected when you submit, not accepted and quietly served in the clear:

apps.grafana.endpoints.web.expose: endpoint "web" is plaintext http; public delivery is
direct (no TLS terminator) — declare protocol "https" and serve TLS with the delivered
certificate, or expose it at project/org scope (on this pool public endpoints are
delivered directly on a public address)

On a pool the access edge serves — one that holds no pool address — plain http can be public: the edge terminates TLS for the browser with its own certificate and reaches the node over its agent's encrypted tunnel, so the service opens at https://{service}.{org zone} and no per-service certificate is ordered for it. Plain http never makes a pool draw an address: a pool whose public endpoints are all http or https, one of them plain http, is served through the edge and draws none, even where one would otherwise be drawn — its https endpoints go through the edge with it. Two cases still deliver directly, and refuse a public plain http endpoint at submission, before anything is drawn:

  • Beside a public tcp or udp endpoint. Only a pool address serves those, and every public endpoint of the pool would be delivered on it. Declare https, keep the http endpoint at project or organization scope, or make the tcp/udp one private so the edge can serve the pool.
  • On a pool that already holds an address. It keeps its address, and an endpoint newly made public in plain http is refused there. An endpoint that was already public is left alone, so the pool goes on reconfiguring.

https, tcp, and udp are publishable wherever the pool can deliver them — the rule is about the missing terminator, not about HTTP. If the app genuinely cannot serve TLS and the pool delivers directly, keep it at project or organization scope, where traffic stays on the overlay.

When one pool exposes several public services, the app recipe narrows which of them a binding is for with the sans parameter on tls.cert — the service name, or its full public name — because one binding delivers one certificate. Public and internal names never share a certificate: a public authority will not certify an .internal name, so a request mixing the two is refused.

A publicly exposed service's name goes into public Certificate Transparency logs, which is the same name you already publish in public DNS for anyone to look up — the log discloses nothing you had not already disclosed. Everything you keep at project or organization scope appears in no public DNS zone, in no publicly issued certificate, and in no transparency log.