Skip to content

inceptionstack/standalone-remote-access-ui

Repository files navigation

Standalone Remote Access Terminal UI

A production-ready, protocol-agnostic browser terminal. The UI renders an xterm.js terminal connected to a WebSocket provided by your backend API. The backend decides the connection protocol (SSH, AWS SSM, GCP IAP, Azure Bastion, etc.) — the UI is purely a WebSocket terminal client.

How It Works

Browser                     Backend API                Cloud Provider
  |                            |                           |
  |-- GET /api/sessions/:id -->|                           |
  |<-- { websocketUrl } -------|                           |
  |                            |                           |
  |== WebSocket ===============|== SSH/SSM/IAP/etc. ======>|
  |   (raw text/binary)        |   (protocol-specific)     |
  1. User authenticates (OIDC/Cognito)
  2. App calls GET /api/sessions/{envId} with Bearer token
  3. Backend returns { websocketUrl, sessionId }
  4. xterm.js connects to the WebSocket URL
  5. User input flows as raw text; backend output flows as text/binary

Local Development

npm install
npm run dev

The dev server proxies /api to http://localhost:3001. Set environment variables in .env:

cp .env.example .env
# Edit .env with your OIDC provider details

Docker

Build and Run

docker build -t remote-access-ui .
docker run -p 8080:80 \
  -e AUTH_PROVIDER=oidc \
  -e OIDC_AUTHORITY=https://your-idp.example.com \
  -e OIDC_CLIENT_ID=your-client-id \
  -e API_BASE_URL=/api \
  remote-access-ui

Docker Compose

docker compose up

Environment Variables

Variable Description Default
AUTH_PROVIDER Auth adapter: oidc or cognito oidc
OIDC_AUTHORITY OIDC issuer URL (for oidc) or Cognito domain URL (for cognito)
OIDC_CLIENT_ID OAuth client ID
OIDC_SCOPES OAuth scopes openid email profile
API_BASE_URL Backend API base URL /api
APP_TITLE Application title Remote Access Terminal

In development, prefix with VITE_ (e.g., VITE_AUTH_PROVIDER).

At runtime (Docker), environment variables are injected into config.js by the entrypoint script — no rebuild needed.

Backend API Contract

GET /api/sessions/{envId}

Request:

  • Header: Authorization: Bearer <token>

Response (200):

{
  "websocketUrl": "wss://backend.example.com/ws/session-abc123",
  "sessionId": "session-abc123"
}

WebSocket Protocol

The UI sends and receives raw data over the WebSocket:

UI to Backend:

  • User keystrokes: sent as raw text strings
  • Terminal resize: {"type":"resize","cols":120,"rows":40}

Backend to UI:

  • Terminal output: raw text (string) or binary (ArrayBuffer)

The backend is responsible for translating between this raw WebSocket protocol and the underlying connection (SSH, SSM, etc.).

ECS Deployment

{
  "containerDefinitions": [{
    "name": "remote-access-ui",
    "image": "ghcr.io/inceptionstack/standalone-remote-access-ui:latest",
    "portMappings": [{ "containerPort": 80 }],
    "environment": [
      { "name": "AUTH_PROVIDER", "value": "cognito" },
      { "name": "OIDC_AUTHORITY", "value": "https://your-domain.auth.us-east-1.amazoncognito.com" },
      { "name": "OIDC_CLIENT_ID", "value": "your-client-id" },
      { "name": "API_BASE_URL", "value": "/api" }
    ],
    "healthCheck": {
      "command": ["CMD-SHELL", "wget -qO- http://localhost/health || exit 1"],
      "interval": 30,
      "timeout": 5,
      "retries": 3,
      "startPeriod": 10
    }
  }]
}

Kubernetes Deployment

apiVersion: apps/v1
kind: Deployment
metadata:
  name: remote-access-ui
spec:
  replicas: 2
  selector:
    matchLabels:
      app: remote-access-ui
  template:
    metadata:
      labels:
        app: remote-access-ui
    spec:
      containers:
        - name: ui
          image: ghcr.io/inceptionstack/standalone-remote-access-ui:latest
          ports:
            - containerPort: 80
          env:
            - name: AUTH_PROVIDER
              value: "oidc"
            - name: OIDC_AUTHORITY
              value: "https://your-idp.example.com"
            - name: OIDC_CLIENT_ID
              valueFrom:
                secretKeyRef:
                  name: remote-access-secrets
                  key: oidc-client-id
            - name: API_BASE_URL
              value: "/api"
          livenessProbe:
            httpGet:
              path: /health
              port: 80
            initialDelaySeconds: 5
            periodSeconds: 30
          readinessProbe:
            httpGet:
              path: /health
              port: 80
            initialDelaySeconds: 3
            periodSeconds: 10
---
apiVersion: v1
kind: Service
metadata:
  name: remote-access-ui
spec:
  selector:
    app: remote-access-ui
  ports:
    - port: 80
      targetPort: 80

About

Standalone Remote Access — cloud-agnostic terminal UI (Docker-ready)

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors