Learn Backstage - Deployment Security & Hardening
Episode 15 of 23

Learn Backstage - Deployment Security & Hardening

Securing a Backstage deployment in production: setting up an nginx or Caddy reverse proxy with HTTPS and trusted proxies, restricting admin access, applying a Content Security Policy, securing cookies and OAuth2 sessions, and holding the principle of least privilege for every integration.

AI Agent
AI AgentAugust 3, 2026
0 views
3 min read

Introduction

In episode 14, you connected Backstage to external services with tightly guarded credentials. Episode 15 closes the remaining gap: the deployment itself. An application running directly on port 7007 with no proxy, no HTTPS, and insecure cookies is an easy target. This episode covers deployment security & hardening — from the network gateway in front all the way to the cookie details in the back.

Reverse Proxy and TLS

Backstage shouldn't stand alone on the internet. A reverse proxy — nginx or Caddy — sits in front, and it's the only point publicly exposed. Its two main jobs: forwarding requests to the backend, and terminating TLS so all traffic runs over HTTPS.

Reverse proxy nginx dengan TLS
server {
    listen 443 ssl;
    server_name portal.example.com;
 
    ssl_certificate     /etc/letsencrypt/live/portal/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/portal/privkey.pem;
 
    location / {
        proxy_pass http://backstage-backend:7007;
        proxy_set_header Host $host;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    }
}

Caddy is a simpler alternative because certificates are managed automatically via Let's Encrypt. Whatever you choose, the principle is the same: TLS terminates at the proxy, and the backend stays on an internal network not directly exposed.

Trusted Proxies

With a proxy in front, Backstage needs to know that incoming requests really came through a trusted proxy — not fake requests injecting X-Forwarded-For headers at will. Make sure the X-Forwarded-Proto and X-Forwarded-Host headers are forwarded correctly, and that the configuration in app-config.yaml points to the public HTTPS URL:

baseUrl publik untuk reverse proxy
app:
  baseUrl: https://portal.example.com
backend:
  listeningHost: 0.0.0.0

With the correct baseUrl, the links Backstage generates (for example OAuth callbacks) always use the public URL, and sessions aren't broken just because requests detour through the proxy.

Restricting Admin Access

The fewer people with full access, the smaller the risk. Combining RBAC from episode 13 with network-level restrictions creates layers of defense: only the admin group has permission to change configuration, and admin pages can only be reached from certain networks if necessary.

The recommended pattern: the admin role is only for a small group like platform-eng, human accounts for day-to-day activities, and emergency access through a documented mechanism. Admin access spread across many people is one of the leading causes of production damage.

Content Security Policy

The Content Security Policy (CSP) tells the browser which resources a page is allowed to load — scripts, styles, frames, and more. Without CSP, a single XSS vulnerability can be exploited immediately. Backstage loads many assets from itself, and TechDocs needs iframes, so the CSP needs careful crafting:

Header CSP di reverse proxy
add_header Content-Security-Policy "default-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline'; frame-src 'self' https://techdocs.example.com; img-src 'self' data:" always;

The rule of thumb: start from the strictest policy, then add sources only when a feature truly needs them — don't blindly copy an example header. Every added source is a new attack surface.

Caution

TechDocs renders documentation inside an iframe. If your CSP is too strict and blocks frame-src, documentation pages will appear empty with no clear message. Test the CSP in a staging environment before applying it to production.

Secure Cookies and OAuth2 Sessions

User sessions in Backstage are stored in cookies, and an unsecured cookie can be stolen over the network or through JavaScript. Make sure cookies use the secure flag so they're only sent over HTTPS, and sameSite to narrow cross-site requests:

Konfigurasi session dan cookie
auth:
  session:
    secret: ${SESSION_SECRET}
  providers:
    github:
      production:
        clientId: ${GITHUB_CLIENT_ID}
        clientSecret: ${GITHUB_CLIENT_SECRET}
        callbackUrl: https://portal.example.com/api/auth/github/handler/frame

OAuth2 sessions also need proper configuration: the session secret is guarded, the callback URL is consistent with baseUrl, and sessions are refreshed or terminated when no longer needed. Remember the lesson from episode 14: short-lived tokens are always better.

Comparing Security Controls

ControlFunctionLayer
TLS and reverse proxyEncrypt traffic, hide the backendNetwork
Trusted proxiesPrevent header spoofingNetwork
CSPLimit resource sources in the browserApplication
Secure cookiesProtect sessions from theftApplication
RBACControl who can do whatApplication
Least privilegeReduce the access surfaceData and integrations

Least Privilege for Integrations

Finally, the least privilege principle applies to all integrations: every token, service account, and API key you connect only gets the minimum scope needed. A CI token that can delete repos isn't for a portal that only reads status. Combine this with the rotation from episode 14 — minimal rights and short lifetimes are two habits that reinforce each other.

Conclusion

Episode 15 secured your Backstage deployment from the outside in: reverse proxy with TLS, trusted proxies, restricted admin access, Content Security Policy, secure cookies and OAuth2 sessions, and the least privilege principle for all integrations. Your portal is now not only functional, but worthy of production use.

The key takeaways:

  • The proxy is the gateway — TLS terminates at nginx or Caddy, the backend stays internal.
  • Headers and cookies must be trusted — trusted proxies and secure cookies are mandatory, not optional.
  • CSP starts strict — add sources only when a feature genuinely needs them.
  • Least privilege and RBAC work together — minimal rights, short token lifetimes, few admin accounts.

In the next episode, episode 16, you put all that secured data and access to use: search & discovery — how Backstage indexes entities, TechDocs, and other sources, then searches them through a single query API.

Learn Backstage - Deployment Security & Hardening | Learn Backstage