mirror of
https://github.com/Studio-Saelix/sencho.git
synced 2026-07-26 20:00:08 +00:00
be22e3ded1
Rewrite docs/features/api-tokens.mdx (115 → 442 lines) as a full product + technical guide: mental model, scope ladder, prerequisites, step-by-step usage with HTTP/WS/multi-node examples, complete universal- restriction table, cross-node proxy behaviour, lifecycle, rate-limit ceiling, security model, limitations, three example workflows, troubleshooting accordion, FAQ accordion. Replace the single populated-list screenshot with five captured against production: empty state, create form, reveal banner (token value redacted), populated list with all three scope variants, revoke modal. Sibling-doc edits keep tier statements coherent now that API tokens are available on every tier: - docs/api-reference/overview.mdx: drop the Admiral-only Note callout, drop API Tokens from the Admiral-gated license-tier table, correct the rate-limit table to say tokens are keyed per-credential - docs/features/overview.mdx: drop the "Admiral only." sentence - docs/security.mdx: drop "Admiral tier.", move API tokens row to every tier in the security matrix, repoint image to the new populated shot
206 lines
6.6 KiB
Plaintext
206 lines
6.6 KiB
Plaintext
---
|
|
title: API Overview
|
|
description: Authenticate, route requests to nodes, and integrate Sencho into your CI/CD pipelines.
|
|
---
|
|
|
|
Sencho exposes a REST API for automating stack deployments, managing webhooks, monitoring fleet health, and integrating with CI/CD pipelines. Since Sencho is self-hosted, the API base URL is your own instance.
|
|
|
|
## Base URL
|
|
|
|
```
|
|
https://your-sencho-instance:1852/api
|
|
```
|
|
|
|
Replace with your actual Sencho host and port. All API paths are prefixed with `/api`.
|
|
|
|
## Authentication
|
|
|
|
Authenticated endpoints require a **Bearer token** in the `Authorization` header. Generate API tokens from **Settings > API Tokens** in the Sencho dashboard.
|
|
|
|
```bash
|
|
curl -H "Authorization: Bearer YOUR_API_TOKEN" \
|
|
https://your-sencho-instance:1852/api/stacks
|
|
```
|
|
|
|
API tokens are 56-character opaque strings that begin with `sen_sk_`, for example `sen_sk_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx`. The prefix makes them easy to identify in logs and is recognized by secret-scanning tools (GitHub, TruffleHog, GitGuardian).
|
|
|
|
### Token scopes
|
|
|
|
Every token is created with one of three permission levels:
|
|
|
|
| Scope | Allowed actions |
|
|
|-------|----------------|
|
|
| **Read Only** | `GET` requests only — view stacks, containers, and fleet status |
|
|
| **Deploy Only** | Everything in Read Only, plus stack operations: deploy, down, restart, stop, start, update |
|
|
| **Full Admin** | Full stack, container, and node management — all read and write operations |
|
|
|
|
Regardless of scope, all API tokens are blocked from managing other tokens, users, licenses, and SSO configuration.
|
|
|
|
## Node routing
|
|
|
|
Sencho manages multiple nodes (local and remote). To target a specific node, include one of:
|
|
|
|
- **Header:** `x-node-id: 1`
|
|
- **Query parameter:** `?nodeId=1`
|
|
|
|
If omitted, the request targets the default node.
|
|
|
|
```bash
|
|
# Target node ID 2
|
|
curl -H "Authorization: Bearer TOKEN" \
|
|
-H "x-node-id: 2" \
|
|
https://your-sencho-instance:1852/api/stacks
|
|
```
|
|
|
|
## Error format
|
|
|
|
All error responses follow the same shape:
|
|
|
|
```json
|
|
{
|
|
"error": "Human-readable error message",
|
|
"code": "MACHINE_READABLE_CODE"
|
|
}
|
|
```
|
|
|
|
The `code` field is present for specific error types:
|
|
|
|
| Code | Meaning |
|
|
|------|---------|
|
|
| `PAID_REQUIRED` | Endpoint requires a Skipper or Admiral license |
|
|
| `ADMIRAL_REQUIRED` | Endpoint requires an Admiral license |
|
|
| `SCOPE_DENIED` | API token scope does not allow this operation |
|
|
|
|
## Input validation
|
|
|
|
All endpoints that accept a `stackName` path parameter validate it against the pattern `^[a-zA-Z0-9_-]+$`. Stack names may only contain **alphanumeric characters, hyphens, and underscores**. Requests with invalid stack names are rejected immediately:
|
|
|
|
```json
|
|
// 400 Bad Request
|
|
{
|
|
"error": "Invalid stack name"
|
|
}
|
|
```
|
|
|
|
This applies to all stack endpoints: read, write, deploy, down, restart, stop, start, update, rollback, backup, delete, and container listing.
|
|
|
|
## Rate limiting
|
|
|
|
Sencho uses a tiered rate limiting system that balances security with usability:
|
|
|
|
| Tier | Limit | Applies to | Keyed by |
|
|
|------|-------|------------|----------|
|
|
| **Polling** | 300/min | Dashboard status endpoints (`/stats`, `/system/stats`, `/stacks/statuses`, etc.) | User session or API token |
|
|
| **Standard** | 200/min | All other API endpoints | User session or API token |
|
|
| **Webhooks** | 500/min | `POST /webhooks/:id/trigger` | IP address |
|
|
| **Auth** | 5-10/15min | Login, setup, SSO endpoints | IP address |
|
|
|
|
Authenticated requests are rate-limited per credential (per user session, or per API token). This prevents teams behind shared NAT or VPN from pooling rate limit budgets, and lets two API-token-driven automations under the same account run on independent budgets. Unauthenticated requests fall back to IP-based limiting.
|
|
|
|
Internal node-to-node traffic (requests authenticated with node proxy tokens) bypasses rate limiting entirely.
|
|
|
|
When exceeded, the server responds with `429 Too Many Requests`:
|
|
|
|
```json
|
|
{
|
|
"error": "Too many requests. Please try again shortly."
|
|
}
|
|
```
|
|
|
|
Standard rate limit headers (`RateLimit-Limit`, `RateLimit-Remaining`, `RateLimit-Reset`) are included in all API responses, so clients can self-throttle accordingly.
|
|
|
|
The default limits can be tuned via environment variables (`API_RATE_LIMIT`, `API_POLLING_RATE_LIMIT`). See [Self-Hosting](/operations/self-hosting) for details.
|
|
|
|
## License tier requirements
|
|
|
|
Some endpoints are gated by license tier:
|
|
|
|
| Tier | Gated features |
|
|
|------|---------------|
|
|
| **Skipper+** | Webhooks, Fleet snapshots, Stack rollback |
|
|
| **Admiral** | Scheduled Tasks |
|
|
|
|
Requests to gated endpoints on a lower tier return `403` with the appropriate error code.
|
|
|
|
## WebSocket endpoints
|
|
|
|
Sencho also provides real-time streaming via WebSocket connections. These are not part of the OpenAPI spec (OpenAPI does not support WebSocket protocols) but are documented here for completeness.
|
|
|
|
### Stack log streaming
|
|
|
|
Stream live logs from a stack's containers.
|
|
|
|
**URL:** `wss://your-sencho-instance:1852/api/stacks/{stackName}/logs?nodeId={nodeId}`
|
|
|
|
**Authentication:** Pass the token as a cookie (`sencho_token`) or Bearer token. For WebSocket connections, authentication is verified during the upgrade handshake.
|
|
|
|
<CodeGroup>
|
|
|
|
```javascript Node.js
|
|
import WebSocket from "ws";
|
|
|
|
const ws = new WebSocket(
|
|
"wss://your-sencho-instance:1852/api/stacks/my-app/logs",
|
|
{ headers: { Cookie: "sencho_token=YOUR_JWT" } }
|
|
);
|
|
|
|
ws.on("message", (data) => {
|
|
console.log(data.toString());
|
|
});
|
|
```
|
|
|
|
```bash cURL (upgrade check)
|
|
curl -i -N \
|
|
-H "Connection: Upgrade" \
|
|
-H "Upgrade: websocket" \
|
|
-H "Cookie: sencho_token=YOUR_JWT" \
|
|
https://your-sencho-instance:1852/api/stacks/my-app/logs
|
|
```
|
|
|
|
</CodeGroup>
|
|
|
|
### Container exec
|
|
|
|
Open an interactive shell session inside a running container.
|
|
|
|
**URL:** `wss://your-sencho-instance:1852/ws`
|
|
|
|
**Authentication:** Cookie-based JWT only. API tokens with `read-only` or `deploy-only` scope are blocked.
|
|
|
|
<CodeGroup>
|
|
|
|
```javascript Node.js
|
|
import WebSocket from "ws";
|
|
|
|
const ws = new WebSocket("wss://your-sencho-instance:1852/ws", {
|
|
headers: { Cookie: "sencho_token=YOUR_JWT" },
|
|
});
|
|
|
|
ws.on("open", () => {
|
|
// Initiate exec session
|
|
ws.send(
|
|
JSON.stringify({
|
|
action: "execContainer",
|
|
containerId: "abc123...",
|
|
})
|
|
);
|
|
});
|
|
|
|
ws.on("message", (data) => {
|
|
// Terminal output
|
|
process.stdout.write(data.toString());
|
|
});
|
|
|
|
// Send terminal input
|
|
ws.send(JSON.stringify({ type: "input", data: "ls -la\n" }));
|
|
|
|
// Resize terminal
|
|
ws.send(JSON.stringify({ type: "resize", cols: 120, rows: 40 }));
|
|
```
|
|
|
|
</CodeGroup>
|
|
|
|
<Warning>
|
|
Container exec requires an **admin** role. API tokens with `read-only` or `deploy-only` scope are blocked, as are node proxy tokens.
|
|
</Warning>
|