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.com)
  • 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.

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.com
Target: http://localhost:8080 on my-server
Authentication: Required (OAuth)
Status: Enabled

Members of your organization (and anyone you authorize — 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.

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.

Ask for the check to be made on the node instead:

Curl http://127.0.0.1:8080 on my-server and tell me the status code

The other confirmation is 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.

Going public needs an Owner or Admin

Publishing a service is something any organization Member may do, and everything a Member publishes is reachable only by people who can authenticate. Turning that authentication offauth_required: false on service_publish, or clearing it later with service_update — needs the Owner or Admin role, because it changes the audience from your organization to anyone holding the URL. Below that role the call returns forbidden and nothing is published or changed; retrying will not help. Publish with authentication on and ask an Owner or Admin if the endpoint really must be public.

Only the transition is gated. Turning authentication back on is never gated, editing any other field of a service that is already public is never gated, and passing authorized_emails forces authentication on, so it is never gated either. See Roles.

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-admin: 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 an elevated terminal is separately gated at the router, and there it fails immediately: admin: true needs 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.

Response Example

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

Terminal URL: https://x9y8z7w6.nobgp.com
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.com

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), members of your organization can access it by default. Access control lets you grant access to people outside your organization — either proactively by adding their email, or by responding to access requests they submit.

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
  • A "Request Access" button

After clicking:

  • 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)

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

Owner Notification

When someone requests access, you receive an email from noreply@nobgp.com:

  • 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.

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 or revoke everyone at once, ask your AI assistant — the service_share tool supports add, remove, list, and revoke.

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.
  • 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.com

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

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.com/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.com (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.com (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.com (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.com
✓ prod-api-1: https://term2.nobgp.com
✓ prod-db-1: https://term3.nobgp.com

All terminals require OAuth authentication.

Troubleshooting

Service Returns 404

Issue: Opening the service URL shows "Not Found"

Solutions:

  • 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

The number of services you can publish is governed by your plan's service allowance — see Plans & Billing. When the cap is reached, service_publish returns a limit error with an upgrade link.

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 account is in good standing. If your organization lapses on payment, reaches its spend cap, or (on the Free plan) exceeds its bandwidth allowance, each of your nodes is throttled to 1 Mbit/s — in both directions — rather than being disconnected, so basic connectivity (DNS, a slow shell, the dashboard) keeps working while bandwidth cost is bounded. The throttle is applied per node, and all services on a node share that node's cap. Throughput returns to full speed once the account is back in good standing (payment resolved, below the spend cap, or upgraded for a larger allowance). 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.