Skip to main content

Publishing Services

Expose web applications and terminals from your nodes to the internet with public HTTPS URLs. No port forwarding, no reverse proxy configuration, no SSL certificates to manage.

Overview​

Service publishing in noBGP creates secure, public endpoints for:

  • Web applications running on your nodes (Proxy Services)
  • Browser-based terminals for remote access (Terminal Services)

All published services get:

  • Unique HTTPS URLs (e.g., https://abc123.nobgp.link)
  • Valid SSL/TLS certificates (automatic)
  • Optional OAuth authentication
  • Enable/disable without deleting
  • Real-time analytics

When authentication is enabled, you control exactly who can access your service — visitors can request access and you approve or deny from the service's permissions page in the noBGP dashboard. See Access Control for details.

Where a service is served​

A published service is served at https://<name>.nobgp.link (router 0.4.172). The <name> label is assigned by noBGP when the service is published — it is not the title you give the service, and no tool renames it — while the domain is the same for every service. Read the whole URL from public_url, which service_publish returns and network_directory reports for each service, rather than assembling it yourself.

nobgp.link is a separate registrable domain from nobgp.com, and that is the point of it. The noBGP dashboard, the API and the MCP endpoint are on nobgp.com; your published service is not. A browser therefore never attaches a nobgp.com cookie to your service, and a page your service serves cannot write one — a published service is arbitrary code, and this is what keeps it out of the dashboard's cookie scope. See Cookie isolation.

An old nobgp.com service URL redirects — update it anyway

Through router 0.4.171 the same service also answered at <name>.nobgp.com. From 0.4.172 that spelling serves no service, and from 0.4.175 it answers a permanent redirect to https://<name>.nobgp.link with the path and the query kept, so an old bookmark or a link you shared still arrives. Your service is unchanged and keeps its name, but its URL is now on nobgp.link: update bookmarks, links you shared, OAuth redirect URIs registered with a third party, and any firewall or proxy allowlist naming the old host. Read the current URL from public_url on network_directory or from the dashboard.

The redirect is a migration aid and will be removed when the old host is retired, and it is not a substitute for the real URL in the meantime: a third party that refuses a redirecting OAuth redirect URI still refuses it, a curl without -L stops at the redirect, and a browser may keep it cached for a day.

The old host answers on every path, and what it answers depends on the name. A GET or HEAD gets a 301 and any other method a 308, which keeps the method and the body — so a POST to an old API URL is not turned into a GET. A name under nobgp.com that has never been a published service answers 404. The names noBGP uses for itself — app, api, mcp, docs, files, router and the rest — are not part of this and are unaffected. ⚠ An old service whose name starts with test- is not redirected: that host belongs to noBGP's test environment, so its old URL still reaches noBGP and not your service.

⚠ A response from the old host is not a sign that your service is reachable. What answers there is noBGP, not your backend. Through router 0.4.174 such a host reached noBGP's own endpoints, so https://<name>.nobgp.com/health answered 200 OK and a monitor polling it stayed green while the service behind it was unreachable. From 0.4.175 it answers the redirect whether your service is up or down, so a check that does not follow redirects, or that counts a 3xx as up, is still green. Point the check at the nobgp.link URL.

/.nobgp/ is reserved on your service's host

Requests whose path starts with /.nobgp/ are the router's and never reach your backend — it answers the sign-in and sign-out paths there and 404s the rest. Every other path is yours and is proxied through untouched. If your app serves something under /.nobgp/, move it.

Service Types​

Proxy Services​

Route public traffic to HTTP applications running on your nodes.

Use cases:

  • Share a development web app with teammates
  • Expose an internal dashboard temporarily
  • Demo an application to clients
  • Access a private admin panel remotely

Example flow:

Terminal Services​

Provide browser-based shell access to your nodes.

Use cases:

  • Remote administration without SSH
  • Share a terminal session with teammates
  • Emergency access when SSH is unavailable
  • Access air-gapped or NAT'd systems

Example flow:

Publishing a Proxy Service​

Basic Proxy​

To expose a web app running on port 8080:

Publish my web app running on localhost:8080 from my-server

Your AI assistant will:

  1. Create a service targeting http://localhost:8080
  2. Generate a unique public URL
  3. Configure HTTPS with valid certificates
  4. Return the URL to you

Response Example​

AI: I've published your web app as a proxy service.

Service URL: https://a1b2c3d4.nobgp.link
Target: http://localhost:8080 on my-server
Authentication: Required (OAuth)
Status: Enabled

The people you name (see Access Control below) can now visit this URL
after signing in.

Specifying Target URLs​

You can specify different targets:

Publish port 3000 from api-server as a public service

or more specifically:

Create a proxy service for http://127.0.0.1:9000/admin on web-server-1

The AI understands various formats and passes the target URL straight through to the service_publish tool — plain URL is the default, no encoding needed:

  • localhost:8080
  • http://localhost:8080
  • http://127.0.0.1:3000/path
  • 0.0.0.0:9000

The target is fetched from the node, so localhost and 127.0.0.1 mean the node itself — which is the common case, and the reason a service on a machine with no public address works at all.

A node refuses a target that is one of the agent's own ports

From agent 0.4.144 a node will not open a connection to its own control surfaces on behalf of a published service: the local MCP server, the shared-drive proxy, the NFS server, the overlay DNS server, the Windows agent API — and port 111, the rpcbind the installer brings in for the drive.

Publishing such a target still succeeds, because publishing only records the route; the first request fails with permission_denied naming the socket that was refused, and service_check reports the same reason. It is the check that already keeps another node off those ports, applied to the other way into them: a service at http://127.0.0.1:<an agent port> — published without authentication, or shared with someone — would otherwise hand a visitor the node's own control surface, and the shared-drive proxy stamps the node's own credentials on every request it forwards.

⚠ It applies to a target on the node itself. Where the target names another machine on the node's LAN, only port 111 is refused: a listener the agent holds here says nothing about the same port over there.

Confirming the Service Actually Works​

A successful publish means the route was recorded. It does not mean the thing behind it is running, and the public URL cannot tell you either: with authentication on — the default — visiting it redirects to the login flow whether the backend answers or not.

Just ask (router 0.4.84+):

Is the backend behind my-dashboard actually up?

That runs service_check, which probes through the same channel a real visitor's request rides and answers one of three things: reachable — with the backend's own status code and how long it took — unreachable, carrying the node's own error text (connection refused, and so on), or not_applicable for a terminal service, which has no backend to reach and where that answer is a success rather than a fault.

⚠ Reachable is not healthy. Any status counts, 500 included: the backend answered, which is a different fact from a refused connection. Read status_code if you need more than "something is listening".

Two older confirmations still work: run the fetch on the node yourself ("curl http://127.0.0.1:8080 on my-server and tell me the status code"), and the backend's own log — once anyone has opened the public URL in a browser, the request shows up there, which proves the whole path end to end.

Authentication Options​

By default, services require OAuth authentication. You can make them public:

Publish my app on port 8080 as a public service (no auth required)

or explicitly require auth:

Publish my admin panel with authentication required
Security

Public services (no auth) can be accessed by anyone with the URL. Only use for demos or truly public applications.

Publishing is the node's controllers'; going public needs an Owner or Admin

From router 0.4.179 publishing, updating, deleting and sharing a service needs control of the node it runs on — the node's owner, or an Owner or Admin of the node's organization. A service belongs to the node, so being able to use the node is not enough, whoever published the services already there. Before that release any Member of the organization could publish on any node in it.

Turning authentication off — auth_required: false on service_publish, or clearing it later with service_update — is a further step up to Owner or Admin, because it changes the audience from the people you named to anyone holding the URL. Below that role the call returns forbidden and nothing is published or changed; retrying will not help.

Only the transition is gated. Turning authentication back on is never gated, a title change on a service that is already public is never gated, and passing authorized_emails forces authentication on, so it is never gated either. ⚠ An update that changes what an already-public proxy exposes — its target, its command, re-enabling it — needs the same role as making it public in the first place.

⚠ A terminal can never be public, for any role: auth_required: false on a terminal or shell service is refused with invalid_args, at publish, at update, and when the router serves it. Only a proxy can be public. See Roles & Permissions.

The Authorization header is your backend's​

noBGP never reads, sets or strips the Authorization header on a request to a published service, and this is an invariant rather than an accident of the implementation (router 0.4.110 pins it in both directions). A visitor to an auth_required service is authenticated by a session cookie, so the router has no use for the header and takes none: it passes to your backend exactly as it was sent.

That means your own API key or bearer scheme keeps working behind a noBGP URL, and the two authentications compose — noBGP decides who may reach the service, your backend decides what that caller may do. It is also why a bearer token belonging to noBGP is never something to send to a published service: on this one path the header is the destination's, not ours. The surfaces that do read a bearer — the MCP endpoint, the REST API, and a shared drive's HTTPS URL — forward the request to no backend at all, so the header can only ever mean one thing on each path.

The Cookie header is filtered in both directions from router 0.4.114, and it is the exact mirror of the rule above: the Authorization header belongs to your backend, and noBGP's own cookies belong to noBGP.

Your service is on its own domain — see Where a service is served. noBGP uses one cookie and one path on your service's host. Everything else is yours.

  • The cookie is __Host-nobgp_sid (router 0.4.174; it was nobgp_sid through 0.4.173, and stays that name over plain http, which is local development only). When a visitor signs in to a service that requires authentication, noBGP sets it on that service's host only. Both names are removed on the way in, so your backend receives neither, and every other cookie pair is passed through byte for byte. That includes names noBGP uses on its own sites, such as workos-access-token: on your host they are your cookies. Through router 0.4.171, while services were on nobgp.com, the browser also sent workos-access-token, workos-refresh-token, workos-session-id and nobgp-user-id, and noBGP removed those four too. From 0.4.172 only the session cookie is removed. noBGP authenticates an auth_required visitor itself, before it proxies, so your backend never needs it.
  • The path is /.nobgp/. noBGP answers under it on every service host, so your app cannot serve a path that starts with /.nobgp/. On your host it answers three paths and 404s every other one: /.nobgp/auth/login and /.nobgp/auth/callback start and finish a sign-in, and /.nobgp/auth/logout (router 0.4.174) signs the visitor out of this service alone. The sign-out is a POST from one of your own pages — any other method, or a form on another site, is refused — so a sign-out button in your app can post to it and needs nothing else. ⚠ It ends the visitor's sign-in on this service, not their noBGP sign-in, so the next protected page here signs them in again with no click. To end both, sign out of the noBGP app. Every path outside /.nobgp/ goes to your backend.

Cookies your backend sets are confined to your own host. A Set-Cookie for either name of noBGP's session cookie is dropped, and a Domain= attribute is removed from everything else, which makes the cookie host-only on your service's hostname. Your service is reachable at one hostname, so a Domain= there could only widen the cookie beyond it, never narrow it within.

⚠ A widened cookie is also a way to break your own backend. A cookie scoped to .nobgp.link would be attached to every other *.nobgp.link host, the Cookie header is one line, and a backend running nginx answers 400 Request Header Or Cookie Too Large once that line passes its default 8 KB buffer. noBGP is never the limiter here — it accepts headers up to 1 MB — so that 400 always comes from your own backend, relayed verbatim.

⚠ Whitespace does not get a cookie past either filter. Browsers strip spaces around a cookie name and around each attribute name before storing anything, so nobgp_sid =x; Domain =.nobgp.link sets the same cookie for the same domain as the unspaced spelling. Both filters compare the trimmed name; through router 0.4.113 a single space defeated the drop and the Domain removal together.

One sign-in covers every service and the app. A visitor who is signed in to noBGP (in the app, or on any service) is not asked to sign in again on another service or in the app: the first visit to each one passes through noBGP's sign-in page and comes straight back, with no click. Several tabs of one service may sign in at the same time. Signing out of the noBGP app signs the visitor out of every service on every device, within about 30 seconds; the /.nobgp/auth/logout path above ends one service's sign-in and leaves the others alone.

The terminal connects to noBGP, not to your service's host. A terminal service's page is in the noBGP app, and its connection goes to router.nobgp.com. It accepts a connection only from the noBGP app or from the service's own page, so another website cannot open a signed-in visitor's terminal.

⚠ The filters cover headers, and the domain covers the noBGP app. A page cannot write a cookie for nobgp.com from nobgp.link, so what a service does in the browser can no longer reach your noBGP dashboard session. ⚠ It can still reach other services: page code can write a cookie for the whole of .nobgp.link with no header involved, and the browser then sends it to every service. Treat anything you publish as code that shares a domain with other people's services. What such a cookie can no longer touch, from 0.4.174, is a visitor's noBGP sign-in on another service: a browser refuses a __Host- cookie that carries a Domain, so only the service's own host can set the name noBGP reads there.

Publishing a Terminal Service​

Basic Terminal​

To create a browser terminal for a node:

Create a browser terminal for my-server

or

Publish a web terminal for raspberry-pi with auth required

You can also specify a specific command to run in the terminal (instead of the default shell) or a working directory:

Publish a terminal on my-server running htop from /var/log
The node still has the last word

Since agent 0.4.33 a terminal service is bound by the target node's own capability settings: a node whose owner removed the command domain from allow-tools refuses the session, and one running with allow-root: false refuses a terminal published to run as root rather than silently running it as another account. Publishing succeeds either way — the refusal appears when someone opens the URL.

The refusal runs in the other direction too. A node with no usable user configured, whose agent runs as root, refuses an unelevated terminal rather than handing out a root shell nobody asked for — publish it with admin: true if the superuser is intended, or configure an account on the node. See Unelevated never means root.

Publishing a root terminal is separately gated at the router, and there it fails immediately: root: true needs root on the node and control of it (the node's owner, or an org Owner or Admin). A published terminal is a standing grant that outlives the call creating it, so the authority is checked when it is created — and again on any later service_update, since changing an already-elevated service's command hands that identity to the new one. See Execution identity.

Everyone the service admits gets the terminal's identity. For an elevated terminal, that is a root shell. See Who can open a service before you publish one.

Response Example​

AI: I've created a browser-based terminal for my-server.

Terminal URL: https://x9y8z7w6.nobgp.link
Authentication: Required (OAuth)
Status: Enabled

Open this URL in your browser to access an interactive shell on my-server.
You'll need to sign in before accessing the terminal.

Using the Terminal​

Once you open the URL:

  1. Sign in with OAuth (if required)
  2. You'll see a full terminal interface
  3. Type commands as if you were SSH'd in
  4. Full support for colors, cursor movement, interactive programs

Terminal Features​

Browser terminals support:

  • Interactive programs: vim, nano, htop, less, etc.
  • Control characters: Ctrl+C, Ctrl+D, Ctrl+L, Ctrl+Z
  • Arrow keys: Navigate command history
  • Tab completion: Works with bash/zsh completion
  • Resize: Automatically adapts to browser window size
  • Copy/paste: Standard browser shortcuts

Managing Services​

Listing Services​

See all your published services:

Show me all my published services

or for a specific node:

What services are published from api-server?

Updating Services​

You can modify service settings:

Make the service abc123 public (remove authentication)

or

Update service xyz789 to require authentication

Removing authentication needs the Owner or Admin role — see above. Putting it back does not.

Disabling/Enabling Services​

Temporarily disable without deleting:

Disable the service at abc123.nobgp.link

Re-enable later:

Enable the service abc123 again
tip

Disabling a service keeps the URL and configuration but makes it inaccessible. This is useful for temporary shutdowns without losing the URL.

Deleting Services​

Permanently remove a service:

Delete the service abc123

or

Remove all services from my-server

The AI will confirm before deleting.

Access Control​

When a service has authentication enabled (auth_required: true), it opens for the people it names — and access control is how you name them, either proactively by adding an address or by answering an access request. For a terminal service, each person it admits gets its shell: see Who can open a service.

A sign-in service opens for its named visitors only, from router 0.4.179

It used to open for every member of your organization. It now opens for:

  • the node's controllers — its owner, and the organization's Owners and Admins;
  • every address on the service's list, exactly or by pattern (*@acme.com);
  • every member of the organization only when you set all_org_members: true on that service — a per-service choice, default off.

So a colleague who could open a service before this release may now meet the Access Required page. Two remedies, and the second is one call: name them (below), or ask your assistant to open this service to the whole organization, which sets all_org_members. Nothing about who may publish changes here — see the note under Authentication Options.

⚠ A root terminal never takes all_org_members, and never a wildcard: naming someone on it hands them a root shell, so each visitor is an exact address and naming anyone who is not one of the node's controllers needs an explicit confirmation. See A root terminal is a root grant.

How It Works​

Visitor Experience​

When a signed-in user tries to access a service they're not authorized for, they are redirected to https://app.nobgp.com/access/<service-name> — an "Access Required" page showing the service name, their signed-in email address, and the state of their request. Opening the page is what submits the request, so:

  • A confirmation appears: "Sent. This page will update when access is granted."
  • The page is notified the moment you approve and redirects to the service automatically (with a 30-second fallback check in case the live connection drops)
  • Reloading it, opening it in a second tab, or retrying the service URL asks again — and does not create a second request. One pending request exists per person per service (router 0.4.78), so two devices asking inside the same moment produce one request, and one email to you.
  • If you have already declined this person, the page says so instead of re-asking. The rejection stands rather than being reopened by a reload — see Access expiry below.

Visitors who aren't signed in are redirected to OAuth login first.

Owner Notification​

When someone requests access, an email from noreply@nobgp.com goes to the owner of the service's node. The node's controllers (its owner, and the organization's Owners and Admins) approve or decline the request. The email is:

  • Subject: Access request for <ServiceTitle>
  • Body: The requester's email address and a "Manage Access" link

The link takes you directly to the service's permissions page in the noBGP dashboard.

You are mailed once per request, not once per page load (router 0.4.78). Because the access page asks on the visitor's behalf every time it is opened, a reload, a second tab or a retry of the service URL all reach noBGP — and none of them reaches your inbox. One email goes out when the request is created; another only if the request is still pending 24 hours later and the person asks again, which is what makes a first email lost to a spam folder recoverable at all. A rejected request never mails you again.

Permissions Page​

Every service has a permissions page in the noBGP dashboard at:

https://app.nobgp.com/permissions/<service-name>

It has two sections:

Pending Requests — approve or reject each request individually.

Authorized Emails — everyone currently approved, each with a Remove button.

To add people proactively, answer a request, or revoke everyone at once, ask your AI assistant — service_share supports add, remove, list, revoke and, from router 0.4.179, approve and reject, which answer one request in a single step. It also names each person on the list: whether the address is a member of the node's organization, and their name when it is. Every action needs control of the node the service runs on, list included.

The mail about a request goes to the owner of the node the service runs on (and, failing that, the network's owner) — the person who can actually answer it.

Email Patterns​

Authorized email entries support wildcards:

PatternWho it matches
user@example.comThat specific user only
*@example.comAnyone with an example.com email
user@*.example.comThat username at any subdomain of example.com

To share a service with your whole team at once:

Add *@yourcompany.com to the authorized list for my-service
tip

The AI assistant can manage the authorized email list using the service_share tool — adding, removing, listing, or revoking all emails. For responding to access requests, use the service's permissions page in the noBGP dashboard.

Access Expiry​

  • Pending requests (not yet approved) expire after 7 days. The requester will need to request again if you don't act in time — asking again after that reuses the same entry rather than leaving the spent one beside it on your permissions page.
  • A rejection stands for 7 days too (router 0.4.78). Declining a request is a decision noBGP keeps: the requester reloading the access page is told they were declined rather than quietly opening a new request and mailing you again. After 7 days they may ask afresh. Changing your mind is unaffected — approving someone you previously declined clears the rejection and grants access normally.
  • Approved access does not expire — it lasts until you remove it from the authorized list or revoke everyone at once via the service_share tool.

Advanced Usage​

Multiple Services Per Node​

You can publish multiple services from the same node:

You: Publish port 8080 from my-server as "app"
AI: ✓ Service created: https://app1.nobgp.link

You: Also publish port 9000 from the same server as "api"
AI: ✓ Service created: https://api2.nobgp.link

Each service gets its own unique URL.

Service Names​

Give services memorable names:

Publish my web app on port 8080 and call it "staging-app"

Later you can reference it by name:

Disable the staging-app service

Custom Paths​

Proxy services can target specific paths:

Publish http://localhost:8080/api from my-server

Requests to https://abc123.nobgp.link/anything will go to http://localhost:8080/api/anything.

WebSocket Support​

Proxy services fully support WebSocket connections, so real-time apps work seamlessly:

Publish my React app with hot-reload on port 3000

The development server's WebSocket for hot-reload will work through the proxy.

Security Best Practices​

1. Use Authentication for Sensitive Services​

Always require OAuth for:

  • Admin panels
  • Internal tools
  • APIs with sensitive data
  • Database management interfaces
Publish my admin panel with authentication required

2. Limit Service Lifespan​

For demos or temporary access:

You: Publish my app on port 8080 as public for the demo
[Give demo]
You: Delete that service now

3. Monitor Access​

Check your published services regularly:

Show me all public services (no auth required)

4. Use Strong Target Security​

Just because a service requires OAuth doesn't mean the underlying app should be insecure:

  • Still use HTTPS in your app if possible
  • Implement application-level authentication
  • Validate all inputs
  • Follow security best practices

5. Rotate URLs Periodically​

For long-running public services, periodically rotate:

Delete service abc123
Publish my app again to get a new URL

Common Patterns​

Development Workflow​

Share work-in-progress with teammates:

You: I need to share my local dev server with the team

AI: I'll publish it as a service with auth required...
✓ https://dev1.nobgp.link (OAuth required)

Share this URL with your teammates. They'll need to sign in with their
noBGP accounts to access it.

Demo to Clients​

Temporarily expose an app:

You: Publish my demo app on port 8080 as public (client demo)

AI: ✓ https://demo1.nobgp.link (public, no auth)

[After demo]

You: Delete the demo service

AI: ✓ Service deleted

Raspberry Pi Access​

Access your Pi's web interfaces:

You: Publish the Pi-hole admin interface from my raspberry-pi

AI: ✓ https://pihole1.nobgp.link (OAuth required)

Access your Pi-hole dashboard from anywhere!

Remote Administration​

Terminal access from anywhere:

You: Create a browser terminal for all my production servers

AI: Creating terminals...
✓ prod-web-1: https://term1.nobgp.link
✓ prod-api-1: https://term2.nobgp.link
✓ prod-db-1: https://term3.nobgp.link

All terminals require OAuth authentication.

Troubleshooting​

Service Returns 404​

Issue: Opening the service URL shows "Not Found"

Solutions:

  • Check the URL is on nobgp.link — a <name>.nobgp.com URL saved before router 0.4.172 serves no service. From router 0.4.175 it redirects to the nobgp.link one; a name that has never been a published service 404s there. ⚠ What the old host answers tells you nothing about your service: open the nobgp.link URL. See Where a service is served
  • Wait 30-60 seconds for DNS propagation
  • Verify service is enabled: "Show me service abc123 status"
  • Check target application is running: "Run 'curl localhost:8080' on my-server"
  • Verify target port is correct

Service Returns 502 Bad Gateway​

Issue: Service URL loads but shows gateway error

Solutions:

  • Confirm target application is running
  • Check target port: "What's listening on port 8080 on my-server?"
  • Verify target URL format (should be http:// not https://)
  • Check application logs

"Access Required" Page Won't Go Away​

Issue: You've been approved but the page isn't refreshing

Solutions:

  • Wait up to 30 seconds — the page falls back to a periodic check if the live update is missed
  • Try a manual refresh if the auto-refresh doesn't trigger
  • Confirm the owner approved (not just rejected) your request
  • Try signing out and back in to refresh your OAuth session

Can't Access Service (Keeps Redirecting to Login)​

Issue: Service requires authentication but OAuth login isn't working

Solutions:

  • Ensure you're signed into a noBGP-compatible OAuth provider
  • Try signing out and back in
  • Check the OAuth provider (Google, GitHub, etc.) isn't having issues
  • Verify the service hasn't been disabled

Terminal Doesn't Respond​

Issue: Browser terminal loads but doesn't show prompt or accept input

Solutions:

  • Refresh the page
  • Check node is still online: "Show me my-server status"
  • Disable/re-enable the service
  • Try creating a new terminal service

WebSocket Connection Failed​

Issue: App works but real-time features don't

Solutions:

  • Verify your app uses relative WebSocket URLs (not absolute)
  • Check firewall settings on the node
  • Ensure WebSocket connections aren't blocked by browser extensions
  • Try a different browser

Limits and Quotas​

Services are unlimited on every plan, including Free — see Plan limits. What can still stop a service_publish is the organization's billing state rather than a service count: a lapsed payment or an empty credit balance refuses new resources, with a limit error carrying an upgrade link. The traffic your services carry counts on the bandwidth meter like any other traffic.

Check your usage:

How many services do I have published?

Next Steps​

FAQ​

Q: Do service URLs ever change? A: No, once created, a service URL remains the same until you delete the service.

Q: Can I use custom domains? A: Not currently. Custom domain support is on the roadmap.

Q: What happens if my node goes offline? A: The service URL remains but will return errors until the node comes back online.

Q: Can I publish services from provisioned nodes? A: Yes! Provisioned nodes work exactly the same as agent-installed nodes.

Q: Is there a bandwidth limit? A: Traffic runs at full speed as long as your organization is within its allowances, and your nodes are never disconnected either way. On a paid plan, a lapsed payment or an empty credit balance throttles each node to 1 Mbit/s in both directions rather than cutting it off, so basic connectivity (DNS, a slow shell, the dashboard) keeps working while the bill is bounded; the throttle is per node, and all services on a node share that node's cap. On the Free plan, from router 0.4.106, passing the 50 GB allowance stops data traffic instead of slowing it — a service keeps its URL and its node stays online, but requests through it are refused until the period rolls over or the organization moves to a paid plan. Either state clears by itself once the trigger does. See Plans & Billing for allowances and rates.

Q: Can I publish HTTPS apps? A: Target URLs should be HTTP. The public service URL is always HTTPS automatically.

Q: How long do terminal sessions last? A: Terminal sessions have a 1-hour idle timeout. After the process exits, there is a 30-second grace period before the session is cleaned up.

Q: Can multiple people use the same terminal service URL? A: Yes, but they'll each get separate shell sessions.

Q: How do I share a service with my team? A: Enable auth_required and either add their emails to the authorized list upfront, or wait for them to request access and approve via the service's permissions page in the noBGP dashboard at https://app.nobgp.com/permissions/<service-name>. You can use *@yourcompany.com to allow everyone at a domain.

Q: Does approved access expire? A: No — once approved, access lasts until you remove it. Pending (unapproved) requests expire after 7 days.

Q: Can I see who has requested or been granted access? A: Yes — visit https://app.nobgp.com/permissions/<service-name> to see pending requests and the full authorized list.