Sign inSign up

descope/engine

By descope

β€’Updated about 14 hours ago

Image
0

50K+

descope/engine repository overview

⁠Descope Engine

The Descope Engine is a lightweight, self-hosted agent that you run inside your own network so Descope connectors can reach resources that are not reachable from the public internet β€” for example an internal HTTP API behind your firewall, a private database, or an on-prem SMTP relay.

The Engine makes a single outbound connection to Descope and executes connector actions locally, so you never have to open inbound ports or expose internal systems to Descope's cloud.

  • πŸ”Œ Executes connector actions (HTTP, SMTP, SQL, etc.) from inside your network
  • ➑️ Outbound-only TLS gRPC connection to Descope β€” no inbound ports
  • 🧱 Stateless container β€” no database or persistent storage to manage
  • πŸ“ˆ Horizontally scalable β€” run multiple replicas with the same Engine ID for high availability
  • πŸ” Automatic reconnection with exponential backoff
  • πŸ›‘οΈ FIPS-validated Node runtime image

⁠How it works

   Your network (private)                        Descope cloud
 β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”        β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
 β”‚                               β”‚  gRPC   β”‚                          β”‚
 β”‚   Engine container  ──────────┼────────►│   Descope Engine service β”‚
 β”‚   (ghcr.io/descope/engine)    β”‚ (TLS,   β”‚   routes connector       β”‚
 β”‚          β”‚                     β”‚ outboundβ”‚   commands               β”‚
 β”‚          β”‚ executes locally    β”‚  only)  β”‚                          β”‚
 β”‚          β–Ό                     β”‚         β”‚                          β”‚
 β”‚  Internal API / DB / SMTP      β”‚         β”‚                          β”‚
 β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜        β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
  1. Connect & authenticate. On startup the Engine opens a long-lived bidirectional gRPC stream out to Descope (TLS by default) and sends a Hello message as the first message on the stream. The Hello carries your Engine ID and Engine Secret. Descope looks up the Engine by ID and verifies the secret. There is no separate token exchange β€” the Hello message is the authentication.
  2. Stay alive. The Engine sends a heartbeat (every 30s by default) and uses HTTP/2 keepalive PINGs so the connection survives idle periods and proxies (e.g. Cloudflare).
  3. Receive & execute. When a flow or connector needs to run, Descope pushes a command down the stream. The Engine executes the connector locally (e.g. calls your internal API) and streams the result back over the same stream.
  4. Reconnect. On any connection failure the Engine reconnects automatically with exponential backoff and re-sends the Hello to re-authenticate.

High availability: run multiple Engine containers with the same Engine ID. Descope automatically distributes commands across the connected replicas (competing consumers), and any replica can execute any connector type.


⁠Get your Engine credentials

Create an Engine and copy its credentials from the Descope Console:

  1. Go to the Descope Console⁠.
  2. Navigate to Connectors β†’ Engines.
  3. Select (or create) your Engine and click Edit.
  4. Copy the Engine ID and Engine Secret.

These map to the ENGINE_ID and ENGINE_SECRET environment variables.


⁠Run with Docker

The Engine is published as ghcr.io/descope/engine and mirrored to Docker Hub as docker.io/descope/engine.

  1. Create an .env file:

    # Required β€” from Descope Console (Connectors β†’ Engines β†’ Edit)
    ENGINE_ID=your-engine-id-here
    ENGINE_SECRET=your-engine-secret-here
    
    # Descope Engine gRPC endpoint (use the endpoint provided by Descope)
    SERVER_ADDRESS=engine.descope.com:443
    USE_SSL=true
    
  2. Run the container:

    docker run --env-file .env ghcr.io/descope/engine
    
  3. For high availability, run the same container on multiple hosts/replicas with the same ENGINE_ID.

The official image already sets ENGINE_IMAGE_VERSION and ENGINE_CONTENT_VERSION (which identify the image and the bundled connector templates), so you do not need to provide them.

The production image is based on Descope's FIPS-validated Node runtime image and invokes the client with node dist/index.js.


⁠Configuration reference

All configuration is provided through environment variables.

⁠Required
VariableDescription
ENGINE_IDEngine ID from the Descope Console. Identifies this Engine; replicas sharing it form one HA group. Your Descope project is derived from this ID.
ENGINE_SECRETEngine Secret from the Descope Console. Sent in the Hello message and verified by Descope on connect.
ENGINE_IMAGE_VERSIONEngine image version identifier. Pre-set in the official image β€” only set this if you build your own image.
ENGINE_CONTENT_VERSIONConnector content (templates) version identifier. Pre-set in the official image.
⁠Connection & TLS
VariableDefaultDescription
SERVER_ADDRESSlocalhost:50051Descope Engine gRPC endpoint (host:port). Set this to the endpoint provided by Descope.
USE_SSLtrueUse TLS for the connection. Keep true in production; set false only for local development.
VERIFY_SERVER_CERTIFICATEtrueVerify the server's TLS certificate. Set false only for self-signed certificates in development.
⁠Timing & keepalive (optional)
VariableDefaultDescription
HEARTBEAT_INTERVAL30000Application-level heartbeat interval (ms).
GRPC_KEEPALIVE_TIME_MS30000HTTP/2 PING interval when idle (ms). Keeps the connection alive through proxies.
GRPC_KEEPALIVE_TIMEOUT_MS20000How long to wait for a PING acknowledgement before dropping the connection (ms).
GRPC_KEEPALIVE_PERMIT_WITHOUT_CALLStrueSend PINGs even when there are no active calls.

The keepalive settings send HTTP/2 PING frames to maintain the connection through proxies (e.g. Cloudflare) and prevent idle-timeout disconnects (such as HTTP 524 errors).

⁠Reconnection (optional)
VariableDefaultDescription
MAX_RECONNECT_ATTEMPTS10Maximum reconnection attempts before the process exits.
BASE_RECONNECT_DELAY1000Initial reconnection delay (ms).
MAX_RECONNECT_DELAY30000Maximum reconnection delay, with jitter (ms).
⁠Logging (optional)
VariableDefaultDescription
LOG_LEVELinfoLog verbosity (fatal, error, warn, info, debug, trace). In production (NODE_ENV=production) logs are JSON; otherwise pretty-printed.

⁠Networking & security

  • Outbound only. The Engine initiates the connection to Descope; you do not open inbound ports.
  • Egress required. Your firewall must allow outbound TLS (typically port 443) to the Descope Engine endpoint.
  • TLS on by default. USE_SSL=true and VERIFY_SERVER_CERTIFICATE=true are the production defaults. The false overrides are for local development only.
  • No datastore. The Engine is stateless β€” there is nothing to back up or persist.
  • Protect the secret. ENGINE_SECRET is a credential. In production, inject it via your orchestrator's secret mechanism rather than a plaintext .env file.

⁠Compliance (FIPS & vulnerability management)

This image is intended for Federal deployments (e.g. FedRAMP Moderate). The notes below describe the technical posture; for formal SLA commitments and signed per-CVE impact statements, contact Descope security/compliance.

⁠FIPS-validated cryptography
  • Validated base. The image is built on a FIPS-validated Node base maintained in Descope's DevOps account (echo/node-fips). All cryptography the client performs β€” notably the TLS gRPC connection to Descope β€” goes through that base's FIPS-validated OpenSSL module.
  • Always on β€” no configuration. FIPS is active by default via the base image's OpenSSL configuration (FIPS provider as default), so crypto.getFips() returns 1 with no flags. Verify directly:
    docker run --rm --entrypoint node descope/engine:latest -p 'crypto.getFips()'   # -> 1
    
  • Fail closed. The client asserts FIPS at startup and refuses to start if it is not active, so a misconfigured runtime cannot silently transact non-validated crypto.
⁠Vulnerability management
  • Scanned every release. Each published image is scanned with Trivy, and a full CVE report plus a CycloneDX SBOM are produced as release artifacts. The pushed image also carries an attached SBOM and build-provenance attestation.
  • Patching. The base is patched by rebuilding on the latest echo/node-fips base; remediation is prioritized by severity, aligned to FedRAMP timelines (High 30 days / Moderate 90 days / Low 180 days). Contact Descope for the formal, signed SLA.
  • Documenting non-impacting CVEs. FedRAMP allows documenting and justifying CVEs rather than patching every one. The per-release CVE report (above) is the basis for those impact statements; Descope can provide justifications for findings that do not affect the service.

⁠Troubleshooting

SymptomLikely cause / fix
Invalid engine secret / auth failure on connectWrong ENGINE_ID or ENGINE_SECRET, or the secret was rotated in the Console. Re-copy both from Connectors β†’ Engines β†’ Edit.
Connection refused / cannot reach serverSERVER_ADDRESS is wrong, or an egress firewall is blocking outbound TLS to Descope.
Connection drops when idle / behind a proxyProxy idle timeout. The keepalive defaults usually fix this; if not, lower GRPC_KEEPALIVE_TIME_MS.
Commands are not being executedConfirm at least one Engine with the correct ENGINE_ID is connected. Check the logs for gRPC stream established with server and Listening for commands.
Need a shell to inspect the containerThe FIPS runtime image is minimal. Override the entrypoint only when the base image includes inspection tooling.

To get more detail, check the container logs β€” the Engine logs connection state, heartbeats, and command execution.


⁠Local development (contributors)

The Engine is a TypeScript application. To run it from source against a local server:

pnpm install

# Configure credentials and a local server address
cp .env.example .env   # then edit ENGINE_ID, ENGINE_SECRET, SERVER_ADDRESS

# Run directly with tsx (no build needed). NODE_TLS_REJECT_UNAUTHORIZED=0
# is only for local servers with self-signed certs.
NODE_TLS_REJECT_UNAUTHORIZED=0 pnpm dev

# Or build and run the bundle
pnpm build
pnpm start

# Type-check and test
pnpm typecheck
pnpm test
⁠Connector templates

Connector behavior is implemented as templates. At startup the Engine discovers templates under src/templates/; each template directory contains a metadata.json (id, name, commands) and an index.mjs exporting async function handler(event). When the server sends an execute command, the Engine routes it to the matching template by templateId. The official image bundles the standard connector templates from ghcr.io/descope/connectors. See src/templates/mock/ for a complete example.

⁠Proto generation

The gRPC types in src/generated/ are generated with ts-proto. After changing the proto definitions, regenerate them from the service root:

cd .. && make proto

Tag summary

Content type

Image

Digest

sha256:e0d2dddec…

Size

126.5 MB

Last updated

about 14 hours ago

docker pull descope/engine