Skip to content

Latest commit

 

History

History
109 lines (73 loc) · 5.85 KB

File metadata and controls

109 lines (73 loc) · 5.85 KB

Security Policy

Supported Versions

Version Supported
latest

Reporting a Vulnerability

Do not open a public issue for security vulnerabilities.

Please report security vulnerabilities via GitHub Security Advisories. This allows us to assess and address the issue privately before public disclosure.

Include as much of the following as possible:

  • Description of the vulnerability
  • Steps to reproduce
  • Affected versions
  • Potential impact
  • Suggested fix (if any)

You should receive an acknowledgment within 48 hours. We will work with you to understand the scope and coordinate a fix and disclosure timeline.

Security Model

sekia is a multi-agent event bus that handles credentials and automates actions across external services. The following security considerations apply:

Authentication & Secrets

  • Never commit secrets. API keys, OAuth tokens, and webhook secrets are configured via environment variables or config files outside the repository.
  • Agent tokens (GITHUB_TOKEN, SLACK_BOT_TOKEN, SLACK_APP_TOKEN, LINEAR_API_KEY, GOOGLE_CLIENT_ID, GOOGLE_CLIENT_SECRET) should follow the principle of least privilege.
  • The Google agent stores OAuth2 tokens on disk (GOOGLE_TOKEN_PATH). Ensure the token file has restrictive permissions (600).

Config Encryption

sekia supports native encryption and secret resolution for values in TOML config files with three backends:

  • age (ENC[...]) — local X25519 encryption via age. Generate keys with sekiactl secrets keygen.
  • AWS KMS (KMS[...]) — encrypt/decrypt via the AWS KMS API. KMS auto-rotation is fully supported.
  • AWS Secrets Manager (ASM[...]) — fetch plaintext secrets by name or ARN. Only plaintext secrets are supported (binary secrets are rejected).

All three formats can be mixed within the same config file and are decrypted transparently at startup.

# age
sekiactl secrets keygen
sekiactl secrets encrypt "ghp_mytoken123"           # → ENC[...]

# AWS KMS
sekiactl secrets kms-encrypt --key-id alias/sekia "ghp_mytoken123"  # → KMS[...]

# Use in config
# github.token = "ENC[YWdlLWVuY3J5cHRpb24...]"
# webhook.secret = "KMS[AQIDAHhB...]"
# nats.token = "ASM[prod/sekia/nats-token]"

Off-machine key support: For age, the decryption key does not need to reside on the same machine. Set SEKIA_AGE_KEY (raw key string) or SEKIA_AGE_KEY_FILE (path to key file) via your secrets manager, CI/CD pipeline, or orchestration tool. Hardware keys are supported via age-plugin-yubikey. For AWS backends, credentials use the standard SDK v2 default chain (environment, profile, instance role, ECS task role).

Key files are stored with 0600 permissions and their parent directories with 0700.

Lua Workflow Sandboxing

  • Lua workflows run in a restricted sandbox: only base (minus dofile/loadfile/load), table, string, and math modules are available. os, io, and debug are excluded.
  • Workflow integrity verification is available: set workflows.verify_integrity = true and maintain a workflows.sha256 manifest generated with sekiactl workflows sign. The engine will reject any .lua file whose hash does not match the manifest.

Named Instance Services

Named agent instances managed via sekiactl service create generate launchd plists (macOS) or systemd units (Linux). The --env KEY=VALUE flag stores environment variables in plaintext within these service files. Prefer using encrypted config values (ENC[...], KMS[...], ASM[...]) in TOML config files instead. Service files are created with 0644 permissions in standard user service directories (~/Library/LaunchAgents/ or ~/.config/systemd/user/).

Network Exposure

  • The embedded NATS server runs in-process with DontListen: true by default — no TCP port is opened for NATS.
  • The Unix socket API is local-only (filesystem permissions).
  • The web dashboard is disabled by default (web.listen = ""). If enabled, it includes CSRF protection (double-submit cookie), security headers (CSP, X-Frame-Options, X-Content-Type-Options, HSTS), and a cap of 50 concurrent SSE connections.
  • The GitHub webhook server validates payloads via HMAC-SHA256 (X-Hub-Signature-256) when a webhook.secret is configured.

Supply Chain

  • Release signing: All release checksums are signed with cosign (Sigstore) using keyless signing via GitHub Actions OIDC. This proves artifacts were built by the official CI pipeline. Each release includes checksums.txt, checksums.txt.sig (signature), and checksums.txt.pem (certificate).
  • SBOM generation: Every release archive includes a CycloneDX JSON Software Bill of Materials (.sbom.json) generated by syft. SBOMs list all Go module dependencies for vulnerability scanning and license compliance.
  • Dependencies are tracked with Dependabot.
  • CI runs go vet and tests on every pull request.

Verifying Release Signatures

Download the release archive, checksums.txt, checksums.txt.sig, and checksums.txt.pem from the GitHub Releases page, then:

# Verify the checksum signature
cosign verify-blob \
  --certificate checksums.txt.pem \
  --signature checksums.txt.sig \
  --certificate-identity-regexp "^https://github\.com/sekia-ai/sekia/" \
  --certificate-oidc-issuer "https://token.actions.githubusercontent.com" \
  checksums.txt

# Verify your archive against the signed checksums
sha256sum --check checksums.txt --ignore-missing

Disclosure Policy

We follow coordinated disclosure. After a fix is available, we will:

  1. Release a patched version
  2. Publish a GitHub Security Advisory
  3. Credit the reporter (unless they prefer anonymity)