UNPKG

signalk-server

Version:

An implementation of a [Signal K](http://signalk.org) server for boats.

654 lines (653 loc) 27.5 kB
{ "openapi": "3.0.0", "info": { "version": "1.0.0", "title": "Signal K Security API", "license": { "name": "Apache 2.0", "url": "http://www.apache.org/licenses/LICENSE-2.0.html" } }, "externalDocs": { "url": "http://signalk.org/specification/", "description": "Signal K specification." }, "servers": [ { "url": "/signalk/v1" } ], "tags": [ { "name": "authentication", "description": "User authentication" }, { "name": "access", "description": "Device access" }, { "name": "oidc", "description": "OpenID Connect (OIDC) configuration" } ], "components": { "schemas": { "IsoTime": { "type": "string", "pattern": "^(\\d{4})-(\\d{2})-(\\d{2})T(\\d{2}):(\\d{2}):(\\d{2}(?:\\.\\d*)?)((-(\\d{2}):(\\d{2})|Z)?)$", "example": "2022-04-22T05:02:56.484Z" }, "RequestState": { "type": "string", "enum": ["PENDING", "FAILED", "COMPLETED"] }, "OIDCPermission": { "type": "string", "enum": ["readonly", "readwrite", "admin"], "description": "Signal K permission level" }, "OIDCConfigResponse": { "type": "object", "description": "OIDC configuration (secrets redacted)", "properties": { "enabled": { "type": "boolean", "description": "Whether OIDC authentication is enabled" }, "issuer": { "type": "string", "description": "OIDC provider issuer URL", "example": "https://auth.example.com" }, "clientId": { "type": "string", "description": "OAuth client ID" }, "clientSecret": { "type": "string", "description": "Always empty (redacted for security)" }, "clientSecretSet": { "type": "boolean", "description": "Whether a client secret has been configured" }, "redirectUri": { "type": "string", "description": "OAuth redirect URI (optional, auto-generated if not set)" }, "scope": { "type": "string", "description": "OAuth scopes to request", "example": "openid email profile" }, "defaultPermission": { "$ref": "#/components/schemas/OIDCPermission" }, "autoCreateUsers": { "type": "boolean", "description": "Automatically create users on first OIDC login" }, "adminGroups": { "type": "array", "items": { "type": "string" }, "description": "Groups that grant admin permission", "example": ["admins", "sk-admin"] }, "readwriteGroups": { "type": "array", "items": { "type": "string" }, "description": "Groups that grant read/write permission", "example": ["users", "operators"] }, "groupsAttribute": { "type": "string", "description": "ID token claim containing user groups", "example": "groups" }, "providerName": { "type": "string", "description": "Display name shown on login button", "example": "SSO Login" }, "autoLogin": { "type": "boolean", "description": "Automatically redirect to OIDC provider when not authenticated" }, "envOverrides": { "type": "object", "description": "Fields that are overridden by environment variables", "additionalProperties": { "type": "boolean" } } } }, "OIDCConfigRequest": { "type": "object", "description": "OIDC configuration update request", "properties": { "enabled": { "type": "boolean" }, "issuer": { "type": "string", "example": "https://auth.example.com" }, "clientId": { "type": "string" }, "clientSecret": { "type": "string", "description": "Leave empty to keep existing secret" }, "scope": { "type": "string", "example": "openid email profile" }, "defaultPermission": { "$ref": "#/components/schemas/OIDCPermission" }, "autoCreateUsers": { "type": "boolean" }, "adminGroups": { "oneOf": [ { "type": "string", "description": "Comma-separated list" }, { "type": "array", "items": { "type": "string" } } ] }, "readwriteGroups": { "oneOf": [ { "type": "string", "description": "Comma-separated list" }, { "type": "array", "items": { "type": "string" } } ] }, "groupsAttribute": { "type": "string" }, "providerName": { "type": "string" }, "autoLogin": { "type": "boolean" } } }, "OIDCTestRequest": { "type": "object", "required": ["issuer"], "properties": { "issuer": { "type": "string", "description": "OIDC provider issuer URL to test", "example": "https://auth.example.com" } } }, "OIDCTestResponse": { "type": "object", "description": "OIDC connection test result", "properties": { "success": { "type": "boolean" }, "issuer": { "type": "string", "description": "Issuer from discovery document" }, "authorization_endpoint": { "type": "string", "description": "OAuth authorization endpoint" }, "token_endpoint": { "type": "string", "description": "OAuth token endpoint" }, "userinfo_endpoint": { "type": "string", "description": "OIDC userinfo endpoint" }, "jwks_uri": { "type": "string", "description": "JSON Web Key Set URI" } } } }, "responses": { "200Ok": { "description": "OK", "content": { "application/json": { "schema": { "type": "object", "properties": { "state": { "type": "string", "enum": ["COMPLETED"] }, "statusCode": { "type": "number", "enum": [200] } }, "required": ["state", "statusCode"] } } } }, "ErrorResponse": { "description": "Failed operation", "content": { "application/json": { "schema": { "type": "object", "description": "Request error response", "properties": { "state": { "type": "string", "enum": ["FAILED"] }, "statusCode": { "type": "number", "enum": [404] }, "message": { "type": "string" } }, "required": ["state", "statusCode", "message"] } } } }, "AccessRequestResponse": { "description": "Request status", "content": { "application/json": { "schema": { "description": "Request response", "type": "object", "required": ["state"], "properties": { "state": { "$ref": "#/components/schemas/RequestState", "default": "PENDING", "example": "PENDING", "description": "Status of request." }, "href": { "type": "string", "example": "/signalk/v1/requests/358b5f32-76bf-4b33-8b23-10a330827185", "description": "Path where the status of the request can be checked." } } } } } }, "RequestStatusResponse": { "description": "Request status", "content": { "application/json": { "schema": { "description": "Request response", "type": "object", "required": ["state"], "properties": { "state": { "$ref": "#/components/schemas/RequestState", "example": "COMPLETED", "default": "COMPLETED", "description": "Status of request." }, "statusCode": { "type": "number", "example": 200, "description": "Response status code." }, "ip": { "type": "string", "example": "192.168.1.77", "description": "IP address of the original access request." }, "accessRequest": { "type": "object", "required": ["permission", "token"], "description": "Access request result.", "properties": { "permission": { "enum": ["DENIED", "APPROVED"], "example": "APPROVED" }, "token": { "type": "string", "description": "Authentication token to be supplied with future requests." }, "expirationTime": { "$ref": "#/components/schemas/IsoTime", "description": "Token expiration time." } } } } } } } } }, "securitySchemes": { "bearerAuth": { "type": "http", "scheme": "bearer", "bearerFormat": "JWT" }, "cookieAuth": { "type": "apiKey", "in": "cookie", "name": "JAUTHENTICATION" } } }, "paths": { "/access/requests": { "post": { "tags": ["access"], "summary": "Create a device access request.", "description": "Endpoint to create (device) access requests. The response contains the href to poll for the status of the request.", "requestBody": { "required": true, "content": { "application/json": { "schema": { "type": "object", "required": ["clientId", "description"], "properties": { "clientId": { "type": "string", "description": "Client identifier.", "example": "1234-45653-343453" }, "description": { "type": "string", "description": "Description of device.", "example": "humidity sensor" } } } } } }, "responses": { "200": { "$ref": "#/components/responses/AccessRequestResponse" }, "default": { "$ref": "#/components/responses/ErrorResponse" } } } }, "/requests/{id}": { "parameters": [ { "name": "id", "in": "path", "description": "request id", "required": true, "schema": { "type": "string" } } ], "get": { "tags": ["access"], "summary": "Check device access status.", "description": "Returns the status of the supplied request id.", "responses": { "200": { "$ref": "#/components/responses/RequestStatusResponse" }, "default": { "$ref": "#/components/responses/ErrorResponse" } } } }, "/auth/login": { "post": { "tags": ["authentication"], "summary": "Authenticate user.", "description": "Authenticate to server using username and password.", "requestBody": { "required": true, "content": { "application/json": { "schema": { "type": "object", "required": ["username", "password"], "properties": { "username": { "type": "string", "description": "User to authenticate" }, "password": { "type": "string", "description": "Password for supplied username." } } } } } }, "responses": { "200": { "description": "Successful Authentication response.", "content": { "application/json": { "schema": { "description": "Login success result", "type": "object", "required": ["token"], "properties": { "token": { "type": "string", "description": "Authentication token to be supplied with future requests." }, "timeToLive": { "type": "number", "description": "Token validity time (seconds)." } } } } } }, "default": { "$ref": "#/components/responses/ErrorResponse" } } } }, "/auth/logout": { "put": { "tags": ["authentication"], "summary": "Log out user.", "description": "Log out the user with the token supplied in the request header.", "security": ["cookieAuth", "bearerAuth"], "responses": { "200": { "$ref": "#/components/responses/200Ok" }, "default": { "$ref": "#/components/responses/ErrorResponse" } } } }, "/security/oidc": { "get": { "tags": ["oidc"], "summary": "Get OIDC configuration.", "description": "Returns the current OIDC configuration with secrets redacted. Includes indicators for fields overridden by environment variables.", "security": [{ "cookieAuth": [] }, { "bearerAuth": [] }], "responses": { "200": { "description": "OIDC configuration", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/OIDCConfigResponse" } } } }, "401": { "description": "Unauthorized - admin access required", "content": { "application/json": { "schema": { "type": "string", "example": "Security config not allowed" } } } } } }, "put": { "tags": ["oidc"], "summary": "Update OIDC configuration.", "description": "Updates the OIDC configuration. Fields set via environment variables cannot be overridden. Leave clientSecret empty to preserve the existing secret.", "security": [{ "cookieAuth": [] }, { "bearerAuth": [] }], "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/OIDCConfigRequest" } } } }, "responses": { "200": { "description": "Configuration saved successfully", "content": { "application/json": { "schema": { "type": "object", "properties": { "message": { "type": "string", "example": "OIDC configuration saved" } } } } } }, "400": { "description": "Invalid configuration", "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "string", "example": "Invalid issuer URL" } } } } } }, "401": { "description": "Unauthorized - admin access required" }, "500": { "description": "Failed to save configuration", "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "string", "example": "Unable to save OIDC configuration" } } } } } } } } }, "/security/oidc/test": { "post": { "tags": ["oidc"], "summary": "Test OIDC connection.", "description": "Tests connectivity to an OIDC provider by fetching its discovery document. Returns the provider's endpoints if successful.", "security": [{ "cookieAuth": [] }, { "bearerAuth": [] }], "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/OIDCTestRequest" } } } }, "responses": { "200": { "description": "Connection successful", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/OIDCTestResponse" } } } }, "400": { "description": "Invalid request", "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "string", "example": "Issuer URL is required" } } } } } }, "401": { "description": "Unauthorized - admin access required" }, "502": { "description": "Failed to connect to OIDC provider", "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "string", "example": "Failed to fetch OIDC discovery document" } } } } } } } } } } }