Files
2026-04-05 12:14:39 +07:00

4.4 KiB

Postiz CLI Auth Server

Device flow OAuth2 server that allows CLI users to authenticate without needing client credentials. The server holds the OAuth app secret and mediates the authorization flow.

How it works

CLI                        Auth Server                    Postiz
 │                              │                           │
 ├─ POST /device/code ─────────►│                           │
 │◄── device_code + user_code ──│                           │
 │                              │                           │
 │  User opens browser ────────►│                           │
 │  Enters code                 │                           │
 │                              ├─ redirect to OAuth ──────►│
 │                              │◄── callback with code ────│
 │                              ├─ exchange for token ─────►│
 │                              │◄── access_token ──────────│
 │                              │  (stored in Postgres)     │
 │                              │                           │
 │  POST /device/token (poll) ─►│                           │
 │◄── access_token ─────────────│                           │

Prerequisites

  • Node.js >= 18
  • PostgreSQL

Environment Variables

Variable Required Default Description
DATABASE_URL Yes - Postgres connection string
POSTIZ_OAUTH_CLIENT_ID Yes - OAuth app client ID from Postiz
POSTIZ_OAUTH_CLIENT_SECRET Yes - OAuth app client secret from Postiz
PORT No 3111 Server port
SERVER_URL No http://localhost:{PORT} Public URL of this server (used for generating links)
POSTIZ_FRONTEND_URL No https://platform.postiz.com Postiz frontend URL for OAuth redirects
POSTIZ_API_URL No https://api.postiz.com Postiz API URL for token exchange

Setup

1. Create an OAuth app in Postiz

Go to Postiz Settings → Developer → OAuth Apps and create a new app. Set the callback URL to:

https://your-server-domain.com/device/callback

2. Set up Postgres

Create a database. The server auto-creates the device_requests table on startup.

3. Configure environment

export DATABASE_URL="postgresql://user:password@localhost:5432/postiz_auth"
export POSTIZ_OAUTH_CLIENT_ID="pca_xxx"
export POSTIZ_OAUTH_CLIENT_SECRET="pcs_xxx"
export SERVER_URL="https://cli-auth.postiz.com"

4. Run

# Install dependencies
pnpm install

# Development
pnpm dev

# Production
pnpm build
pnpm start:prod

Endpoints

Method Path Description
POST /device/code CLI calls this to start a new device flow. Returns device_code, user_code, and verification_uri.
GET /device/verify Browser page where the user enters their code. Accepts optional ?code= query param to prefill.
POST /device/verify Validates the user code and redirects to Postiz OAuth.
GET /device/callback Postiz redirects here after authorization. Exchanges the auth code for a token and stores it.
POST /device/token CLI polls this with {"device_code": "..."}. Returns authorization_pending until the user completes auth, then returns the token.
GET /health Health check. Returns {"status": "ok"}.

Database

The server uses a single table that is auto-created on startup:

CREATE TABLE device_requests (
  device_code TEXT PRIMARY KEY,
  user_code TEXT NOT NULL,
  status TEXT NOT NULL DEFAULT 'pending',  -- 'pending' or 'completed'
  access_token TEXT,
  api_url TEXT,
  organization_id TEXT,
  created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);

Rows are deleted after the CLI retrieves the token, or on next access if expired (15 minutes).

Deployment

Any platform that runs Node.js and can connect to Postgres works (Railway, Fly.io, Render, VPS, etc.).

The server is stateless beyond Postgres, so it scales horizontally — run multiple instances behind a load balancer if needed.