From 41b9f21255f1a8a43084f0c81f1aa6a32454821a Mon Sep 17 00:00:00 2001 From: krakenhavoc Date: Fri, 27 Mar 2026 18:53:47 +0000 Subject: [PATCH] docs: v0.1.0 --- .env.example | 3 +- CHANGELOG.md | 25 ++++++++++++++ CONTRIBUTING.md | 71 ++++++++++++++++++++++++++++++++++++++ README.md | 90 ++++++++++++++++++++++++++++++++++++++++--------- SECURITY.md | 46 +++++++++++++++++++++++++ 5 files changed, 219 insertions(+), 16 deletions(-) create mode 100644 CHANGELOG.md create mode 100644 CONTRIBUTING.md create mode 100644 SECURITY.md diff --git a/.env.example b/.env.example index cfd3b6e..e2060b3 100644 --- a/.env.example +++ b/.env.example @@ -2,9 +2,10 @@ # KrakenKey Probe Configuration # ################################## -# Mode: "standalone" or "connected" +# Mode: "standalone", "connected", or "hosted" # standalone - fully local, no API communication, results logged only # connected - endpoints managed in KrakenKey dashboard, fetched from API +# hosted - fully managed by KrakenKey infrastructure KK_PROBE_MODE=standalone # Probe display name (shown in health endpoint / dashboard) diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..dbc904b --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,25 @@ +# Changelog + +All notable changes to this project will be documented in this file. + +The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), +and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). + +## [0.1.0] - 2026-03-17 + +### Added + +- TLS endpoint scanner with certificate metadata extraction (subject, SANs, issuer, chain, expiry, fingerprint, key type, signature algorithm) +- Connection metadata collection (TLS version, cipher suite, handshake latency, OCSP stapling) +- Three operating modes: `standalone`, `connected`, and `hosted` +- KrakenKey API integration for probe registration and result reporting +- Health check server with `/healthz` and `/readyz` endpoints +- Configurable scan interval (1m to 24h) with immediate first scan on startup +- YAML config file with environment variable overrides (`KK_PROBE_*` prefix) +- Persistent probe ID across restarts via state file +- Graceful shutdown on SIGINT/SIGTERM +- Multi-platform Docker images (linux/amd64, linux/arm64) via GoReleaser +- CI pipeline with lint, test, and build matrix +- Kubernetes deployment example with ConfigMap, Secrets, and health probes + +[0.1.0]: https://github.com/krakenkey/probe/releases/tag/v0.1.0 diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 0000000..5dad375 --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,71 @@ +# Contributing to KrakenKey Probe + +Thank you for your interest in contributing! This guide will help you get started. + +## Getting Started + +### Prerequisites + +- [Go 1.23+](https://go.dev/dl/) +- [golangci-lint](https://golangci-lint.run/welcome/install-locally/) (for linting) +- Docker (optional, for container builds) + +### Clone and Build + +```bash +git clone https://github.com/krakenkey/probe.git +cd probe +go build -o krakenkey-probe ./cmd/probe +``` + +### Run Tests + +```bash +go test ./... -race +``` + +### Run Linter + +```bash +golangci-lint run +``` + +## Project Structure + +``` +cmd/probe/ Entry point (CLI flags, startup, shutdown) +internal/ + config/ Configuration loading, env overrides, validation + health/ HTTP health check server (/healthz, /readyz) + reporter/ KrakenKey API client (registration, reporting) + scanner/ TLS endpoint scanner (certificate extraction) + scheduler/ Scan scheduling and orchestration + state/ Probe ID generation and persistence +``` + +## Development Workflow + +1. **Fork** the repository and create a feature branch from `main`. +2. **Make your changes** with clear, focused commits. +3. **Run tests and lint** before pushing: + ```bash + go test ./... -race && golangci-lint run + ``` +4. **Open a pull request** against `main` with a clear description of what and why. + +## Code Guidelines + +- Keep dependencies minimal. The project intentionally uses only `gopkg.in/yaml.v3` beyond the standard library. +- Use `log/slog` for structured logging. Follow the existing patterns for log levels and context. +- Write tests for new functionality. Use `go test -race` to catch concurrency issues. +- Follow standard Go conventions (`gofmt`, `go vet`). + +## Reporting Issues + +- Use [GitHub Issues](https://github.com/krakenkey/probe/issues) to report bugs or request features. +- Include your Go version, OS/architecture, and probe version (`krakenkey-probe --version`). +- For bugs, include relevant log output (with `KK_PROBE_LOG_LEVEL=debug` if possible). + +## License + +By contributing, you agree that your contributions will be licensed under the [AGPL-3.0](LICENSE) license. diff --git a/README.md b/README.md index d72b2a4..0f54419 100644 --- a/README.md +++ b/README.md @@ -10,31 +10,70 @@ The probe connects to configured endpoints via TLS, extracts certificate and con ## Quick Start +### Standalone (no API key needed) + ```bash docker run -d \ - -e KK_PROBE_API_KEY="kk_your_api_key" \ -e KK_PROBE_ENDPOINTS="example.com:443,api.example.com:443" \ -e KK_PROBE_NAME="my-probe" \ -v probe_state:/var/lib/krakenkey-probe \ ghcr.io/krakenkey/probe:latest ``` +### Connected (reports to KrakenKey) + +```bash +docker run -d \ + -e KK_PROBE_MODE="connected" \ + -e KK_PROBE_API_KEY="kk_your_api_key" \ + -e KK_PROBE_NAME="my-probe" \ + -v probe_state:/var/lib/krakenkey-probe \ + ghcr.io/krakenkey/probe:latest +``` + +## Operating Modes + +The probe supports three operating modes: + +| Mode | API Key | Endpoints | Description | +|---|---|---|---| +| `standalone` | Not required | Defined locally in config/env | Fully local. Scans endpoints and logs results to console. No API communication. | +| `connected` | Required (`kk_` prefix) | Managed via KrakenKey dashboard | Endpoints fetched from API. Results reported to KrakenKey for dashboard monitoring. | +| `hosted` | Required (service key) | Managed by KrakenKey | Fully managed by KrakenKey infrastructure. Probe ID, name, and region are pre-configured. | + +Set the mode with `KK_PROBE_MODE` or `probe.mode` in the YAML config. Default: `standalone`. + +## CLI Flags + +``` +krakenkey-probe [flags] + +Flags: + --config Path to probe.yaml config file + --version Print version and exit + --healthcheck Check health endpoint (http://localhost:8080/healthz) and exit with 0 (healthy) or 1 (unhealthy) +``` + ## Configuration -The probe is configured via a YAML file and/or environment variables. Environment variables take precedence over YAML values. +The probe is configured via a YAML file and/or environment variables. Configuration is loaded in order of precedence (highest wins): + +1. **Environment variables** (`KK_PROBE_*` prefix) +2. **YAML config file** (if `--config` is provided) +3. **Built-in defaults** ### YAML Config ```yaml api: url: "https://api.krakenkey.io" # KK_PROBE_API_URL - key: "kk_..." # KK_PROBE_API_KEY (required) + key: "" # KK_PROBE_API_KEY (required for connected/hosted modes) probe: id: "" # KK_PROBE_ID (auto-generated if empty) name: "my-probe" # KK_PROBE_NAME - mode: "self-hosted" # KK_PROBE_MODE (self-hosted | hosted) - region: "" # KK_PROBE_REGION + mode: "standalone" # KK_PROBE_MODE (standalone | connected | hosted) + region: "" # KK_PROBE_REGION (required for hosted mode) interval: "60m" # KK_PROBE_INTERVAL (min: 1m, max: 24h) timeout: "10s" # KK_PROBE_TIMEOUT state_file: "/var/lib/krakenkey-probe/state.json" # KK_PROBE_STATE_FILE @@ -42,7 +81,7 @@ probe: endpoints: # KK_PROBE_ENDPOINTS (comma-separated host:port) - host: "example.com" port: 443 - sni: "" # optional SNI override + sni: "" # optional: override the SNI hostname sent during TLS handshake - host: "internal.corp.net" port: 8443 @@ -55,20 +94,24 @@ logging: format: "json" # KK_PROBE_LOG_FORMAT (json|text) ``` +### SNI Override + +Use the `sni` field when the hostname you connect to differs from the hostname expected by the TLS certificate. This is common with load balancers, CDNs, or internal services behind a reverse proxy. If omitted, the `host` value is used as the SNI hostname. + ### Environment Variable Reference | Variable | Default | Description | |---|---|---| | `KK_PROBE_API_URL` | `https://api.krakenkey.io` | KrakenKey API base URL | -| `KK_PROBE_API_KEY` | (required) | API key, must start with `kk_` | +| `KK_PROBE_API_KEY` | | API key (`kk_` prefix). Required for `connected` and `hosted` modes. | | `KK_PROBE_ID` | (auto-generated) | Probe ID, persisted to state file | | `KK_PROBE_NAME` | | Human-friendly probe name | -| `KK_PROBE_MODE` | `self-hosted` | `self-hosted` or `hosted` | -| `KK_PROBE_REGION` | | Geographic region label | -| `KK_PROBE_INTERVAL` | `60m` | Scan interval (Go duration) | +| `KK_PROBE_MODE` | `standalone` | `standalone`, `connected`, or `hosted` | +| `KK_PROBE_REGION` | | Geographic region label (required for `hosted` mode) | +| `KK_PROBE_INTERVAL` | `60m` | Scan interval (Go duration, e.g. `30m`, `1h`) | | `KK_PROBE_TIMEOUT` | `10s` | Per-endpoint TLS dial timeout | | `KK_PROBE_STATE_FILE` | `/var/lib/krakenkey-probe/state.json` | State file path | -| `KK_PROBE_ENDPOINTS` | | Comma-separated `host:port` pairs | +| `KK_PROBE_ENDPOINTS` | | Comma-separated `host:port` pairs. Port defaults to `443` if omitted. | | `KK_PROBE_HEALTH_ENABLED` | `true` | Enable health endpoint | | `KK_PROBE_HEALTH_PORT` | `8080` | Health endpoint port | | `KK_PROBE_LOG_LEVEL` | `info` | Log level | @@ -83,6 +126,7 @@ services: container_name: krakenkey-probe restart: unless-stopped environment: + KK_PROBE_MODE: "connected" KK_PROBE_API_KEY: "kk_your_api_key_here" KK_PROBE_NAME: "my-probe" KK_PROBE_ENDPOINTS: "example.com:443,api.example.com:443" @@ -215,11 +259,11 @@ CGO_ENABLED=0 GOOS=darwin GOARCH=arm64 go build -ldflags="-s -w" -o krakenkey-pr GET /readyz ``` -1. On startup, the probe loads its config, generates or reads its probe ID, and registers with the KrakenKey API. -2. It immediately runs the first scan cycle: connects to each endpoint via TLS, extracts certificate metadata, and sends results to the API. +1. On startup, the probe loads its config and generates or reads its probe ID. In `connected`/`hosted` modes, it registers with the KrakenKey API. +2. It immediately runs the first scan cycle: connects to each endpoint via TLS and extracts certificate metadata. In `connected`/`hosted` modes, results are sent to the API. In `standalone` mode, results are logged to the console. 3. After the first scan, the `/readyz` endpoint returns `200 OK`. 4. Subsequent scans run on the configured interval. -5. On `SIGINT` or `SIGTERM`, the probe finishes the current scan cycle and shuts down. +5. On `SIGINT` or `SIGTERM`, the probe finishes the current scan cycle and shuts down gracefully. ### What Gets Collected @@ -258,18 +302,34 @@ For each endpoint, the probe extracts: ### `/healthz` Response +Always returns `200 OK`: + ```json { "status": "ok", "version": "0.1.0", "probeId": "a1b2c3d4-...", - "mode": "self-hosted", + "mode": "standalone", "region": "us-east-1", "lastScan": "2026-03-17T12:00:00Z", "nextScan": "2026-03-17T13:00:00Z" } ``` +### `/readyz` Response + +Returns `503 Service Unavailable` before the first scan completes: + +```json +{ "status": "not ready" } +``` + +Returns `200 OK` after the first scan completes: + +```json +{ "status": "ready" } +``` + ## Troubleshooting **"api.key is required"** diff --git a/SECURITY.md b/SECURITY.md new file mode 100644 index 0000000..dcaeff1 --- /dev/null +++ b/SECURITY.md @@ -0,0 +1,46 @@ +# Security Policy + +## Reporting a Vulnerability + +If you discover a security vulnerability in KrakenKey Probe, please report it responsibly. + +**Do not open a public GitHub issue for security vulnerabilities.** + +Instead, please email **security@krakenkey.io** with: + +- A description of the vulnerability +- Steps to reproduce +- Potential impact +- Suggested fix (if any) + +We will acknowledge your report within **48 hours** and aim to provide a fix or mitigation within **7 days** for critical issues. + +## Supported Versions + +| Version | Supported | +|---------|-----------| +| 0.1.x | Yes | + +## Security Considerations + +### What the Probe Collects + +The probe connects to TLS endpoints and extracts **publicly available** certificate metadata (subject, issuer, SANs, expiry, etc.) and connection metadata (TLS version, cipher suite, handshake latency). It does not intercept, decrypt, or inspect application-layer traffic. + +### API Key Handling + +- API keys are passed via environment variables or config files and are sent as Bearer tokens over HTTPS. +- Keys are never logged, even at debug level. +- Use Kubernetes Secrets or equivalent mechanisms to manage API keys in production. + +### Container Security + +- The official Docker image runs as a non-root user (UID 65532). +- The image is based on `distroless/static-debian12` to minimize attack surface. +- No shell or package manager is included in the production image. + +### Network + +- Outbound connections are made to configured TLS endpoints and the KrakenKey API (`https://api.krakenkey.io` by default). +- The health server listens on a configurable port (default `8080`) and serves read-only status information. +- No inbound connections are required beyond the health endpoint.