Security & Hardening
BRIDGEPORT secures your infrastructure with JWT authentication, role-based access control, AES-256-GCM encryption for secrets at rest, per-environment SSH keys, and per-server agent tokens.
Security Architecture
Section titled “Security Architecture”BRIDGEPORT uses multiple security layers to protect your deployment infrastructure:
| Layer | Mechanism | Purpose |
|---|---|---|
| Authentication | JWT tokens (7-day expiry) + API tokens | Verify user identity |
| Authorization | RBAC with three roles | Control what users can do |
| Encryption | AES-256-GCM (AEAD) | Protect secrets, SSH keys, and credentials at rest |
| Transport | HTTPS via reverse proxy | Protect data in transit |
| SSH | Per-environment encrypted keys | Isolate server access by environment |
| Agent | Per-server tokens (SHA-256 hashed) | Authenticate agent metric pushes |
| Audit | Comprehensive action logging | Track who did what and when |
Authentication Flow
Section titled “Authentication Flow”sequenceDiagram
participant Client
participant BRIDGEPORT
participant Database
Client->>BRIDGEPORT: POST /api/auth/login (email, password)
BRIDGEPORT->>Database: Verify credentials (bcrypt)
Database-->>BRIDGEPORT: User record
BRIDGEPORT-->>Client: JWT token (7-day expiry)
Client->>BRIDGEPORT: GET /api/servers (Authorization: Bearer <token>)
BRIDGEPORT->>BRIDGEPORT: Verify JWT or API token
BRIDGEPORT->>BRIDGEPORT: Check RBAC role
BRIDGEPORT->>Database: Fetch data
BRIDGEPORT-->>Client: 200 OK (data)
BRIDGEPORT supports two authentication methods:
- JWT tokens — issued on login, expire after 7 days, used by the web UI
- API tokens — long-lived tokens created by users for programmatic access (CI/CD, scripts). Tokens are stored as SHA-256 hashes and cannot be retrieved after creation.
Both methods use the same Authorization: Bearer <token> header. BRIDGEPORT tries API token validation first, then falls back to JWT verification.
RBAC Model
Section titled “RBAC Model”BRIDGEPORT has three roles arranged in a strict hierarchy: admin > operator > viewer.
| Action | Admin | Operator | Viewer |
|---|---|---|---|
| View servers, services, databases | Yes | Yes | Yes |
Reveal secret values (if allowSecretReveal enabled) | Yes | No | No |
| View audit logs | Yes | Yes | Yes |
| Deploy services | Yes | Yes | No |
| Manage secrets (create, update, delete) | Yes | Yes | No |
| Create/trigger backups | Yes | Yes | No |
| Run health checks | Yes | Yes | No |
| Manage config files | Yes | Yes | No |
| Create/delete servers | Yes | No | No |
| Create/delete environments | Yes | No | No |
| Manage users | Yes | No | No |
| System settings | Yes | No | No |
| Environment settings | Yes | No | No |
| SMTP, Slack, webhook configuration | Yes | No | No |
| Service type and database type management | Yes | No | No |
The RBAC middleware is enforced at the route level using requireAdmin and requireOperator preHandlers. Every route that modifies data includes explicit authorization checks.
Encryption at Rest
Section titled “Encryption at Rest”All sensitive data stored in the database is encrypted using AES-256-GCM (Authenticated Encryption with Associated Data):
- Secrets (key-value pairs stored in the Secrets page)
- SSH private keys (per-environment, configured in Settings)
- Registry credentials (tokens and passwords for container registries)
- SMTP passwords (for email notification delivery)
- Slack webhook URLs
- Spaces secret keys (for S3-compatible storage)
How It Works
Section titled “How It Works”- A 32-byte
MASTER_KEYis provided via environment variable - Each encrypted value gets a unique 12-byte random IV (initialization vector)
- AES-256-GCM produces both the ciphertext and a 16-byte authentication tag
- The IV (nonce) and ciphertext+tag are stored as separate base64-encoded fields
Key Management
Section titled “Key Management”- The
MASTER_KEYis never stored in the database. It exists only in your.envfile or environment variables. - If the
MASTER_KEYis lost, all encrypted data becomes irrecoverable. Store it securely in a password manager or secrets vault. - To rotate the
MASTER_KEY, you would need to decrypt all values with the old key and re-encrypt with the new one. There is currently no automated rotation command.
The MASTER_KEY is the single most critical secret in your BRIDGEPORT deployment. Back it up separately from the database. Without it, encrypted secrets, SSH keys, and registry credentials cannot be recovered.
SSH Key Management
Section titled “SSH Key Management”BRIDGEPORT uses per-environment SSH keys for secure server access:
- Each environment has its own SSH private key, configured in Settings > SSH
- Keys are encrypted with AES-256-GCM before being stored in the database
- When BRIDGEPORT needs to connect to a server, it decrypts the key in memory
- Keys are never written to disk in plaintext
This design provides:
- Environment isolation: Staging and production use different keys
- No key files on the container filesystem: Keys exist only in encrypted database storage
- Centralized management: Upload keys once in the UI; they work for all servers in that environment
Agent Token Security
Section titled “Agent Token Security”Each server running the BRIDGEPORT monitoring agent has a unique authentication token:
- Tokens are generated as 32-byte random values (base64url-encoded)
- Only the SHA-256 hash of the token is stored in the database
- The plaintext token is shown once when the agent is deployed, then discarded
- Tokens can be regenerated from the server detail page if compromised
The agent includes the token in every metrics push to authenticate itself. BRIDGEPORT verifies the hash on each request.
MCP Server (Opt-In)
Section titled “MCP Server (Opt-In)”BRIDGEPORT can expose a curated subset of its API to AI agents via the Model Context Protocol. It is disabled by default and is a network-exposed surface, so treat enabling it as a deliberate security decision.
- Off unless explicitly enabled. The
/mcproute is registered only whenMCP_ENABLEDistrue/1. The flag is strict-parsed and fails closed — a literalMCP_ENABLED=false(or0, empty, or unset) keeps it off, and requests return404. It is a deployment-level kill switch (an env var, not a runtime setting): flipping it off and restarting removes the endpoint entirely. - Same auth, same scopes. Every tool replays a real internal API request carrying the caller’s bearer token, so role/scope enforcement, validation, idempotency, and audit logging behave exactly as for a REST call — there is no separate MCP permission model. Mint a dedicated, environment-scoped, role-capped API token per client rather than reusing an admin credential; an env-scoped token is shown only the tools it can actually call.
- Secrets never leave the host. A boundary redactor strips every secret-named field from all tool and resource output;
list_secrets/list_varsreturn no values, and the admin-only secret-reveal endpoint is not exposed as a tool. Decrypted secrets cannot be read through MCP. - Mind data egress. Tool outputs — including container logs and audit entries, which can contain sensitive application output — are sent to whatever model the connected client uses. Only enable MCP, and only mint tokens, for operators you trust to route that data to their model.
- Harden remote exposure. When reaching MCP through a reverse proxy, set
MCP_ALLOWED_HOSTSto the public hostname(s) to enable DNS-rebinding protection, and terminate TLS exactly as for the REST API.MCP_ALLOWED_HOSTSis the public hostname, not the bind address (HOST).
Status, the live endpoint URL, and the full exposed tool/resource inventory are visible to admins at Admin > MCP Server (/admin/mcp). See the MCP Server Reference for client setup, the scope-to-tool mapping, and the full data-egress detail.
Production Hardening Checklist
Section titled “Production Hardening Checklist”Use this checklist to secure your BRIDGEPORT deployment:
-
Run behind a reverse proxy with HTTPS — BRIDGEPORT itself serves HTTP. Use Caddy, nginx, or Traefik to terminate TLS. The included
docker-compose.ymlships with a Caddy configuration. -
Set strong
MASTER_KEYandJWT_SECRET— Generate withopenssl rand -base64 32. Never reuse these values across deployments. -
Change default admin credentials — Set
ADMIN_EMAILandADMIN_PASSWORDin your.envbefore first boot, then change the password via the UI. -
Configure
CORS_ORIGIN— Set this to your specific domain (e.g.,https://deploy.example.com). In production, BRIDGEPORT defaults to rejecting cross-origin requests from unknown domains. -
Run as non-root — The Docker image already runs as the
nodeuser (UID 1000). Thedocker-compose.ymlsetsuser: "1000:1000". -
Restrict network access — Limit access to port 3000 (or your reverse proxy port) to trusted networks. BRIDGEPORT is an internal tool, not a public-facing service.
-
Lock down the MCP server (only if enabled) — The MCP server is off by default. If you set
MCP_ENABLED=true, mint a dedicated env-scoped, role-capped API token per client (never reuse an admin credential), setMCP_ALLOWED_HOSTSwhen exposing it through a reverse proxy, and remember that tool outputs — including logs — are sent to the connected client’s model. Leave it disabled if you don’t use it. -
Set up firewall rules for SSH — BRIDGEPORT connects to your servers via SSH. Ensure only BRIDGEPORT’s IP (or network) can reach port 22 on managed servers.
-
Protect the Docker socket — If using socket mode for host container management, understand that mounting
/var/run/docker.sockgives BRIDGEPORT full Docker daemon access. -
Enable Sentry for error monitoring — Set
SENTRY_BACKEND_DSNandSENTRY_FRONTEND_DSNto catch errors before your users do. Verify end-to-end delivery from Admin > Notifications > Sentry using the per-side test buttons. -
Back up the SQLite database regularly — See Backup & Restore for automated backup strategies.
-
Review audit logs periodically — Check Admin > Audit for unexpected activity. Configure retention via System Settings.
-
Keep BRIDGEPORT updated — Pull the latest image regularly to get security patches. See Upgrades.
Audit Logging
Section titled “Audit Logging”BRIDGEPORT maintains a comprehensive audit trail of all significant actions.
What Gets Audited
Section titled “What Gets Audited”| Category | Actions Tracked |
|---|---|
| Deployments | deploy, restart, rollback |
| Secrets | create, update, delete, access (reveal) |
| User Management | create, update, delete (users and API tokens) |
| Configuration | create, update, delete (servers, services, environments, config files) |
| Backups | backup, restore, schedule changes |
| Registries | create, update, delete, credential changes |
| System Settings | All changes to system-wide and environment settings |
| Storage | Spaces configuration and per-environment toggle changes |
Audit Log Structure
Section titled “Audit Log Structure”Each audit log entry includes:
| Field | Description |
|---|---|
action | What happened (deploy, create, update, delete, access) |
resourceType | What was affected (server, service, secret, environment, etc.) |
resourceId | ID of the affected resource |
resourceName | Human-readable name for display |
details | JSON string with additional context |
success | Whether the action succeeded |
error | Error message if it failed |
userId | Who performed the action |
environmentId | Which environment was affected |
createdAt | When it happened |
Accessing Audit Logs
Section titled “Accessing Audit Logs”- UI: Navigate to Admin > Audit. Filter by environment, resource type, action, and date range.
- API:
GET /api/audit-logswith query parameters for filtering.
Retention
Section titled “Retention”Audit log retention is configurable via Admin > System Settings (auditLogRetentionDays). The default is 90 days. Set to 0 to keep audit logs forever. Cleanup runs automatically once per day.
Vulnerability Reporting
Section titled “Vulnerability Reporting”If you discover a security vulnerability in BRIDGEPORT, please report it responsibly. See SECURITY.md for reporting instructions, response timeline expectations, and the scope of what constitutes a security issue.
Related Documentation
Section titled “Related Documentation”- Backup & Restore — protect your data
- Upgrades — keep BRIDGEPORT patched
- Troubleshooting — debug authentication and access issues
- Configuration Reference — environment variable details