Files
codevault/README.md
Aleksei Sokol 1ccf40396f Version 0.2.0
Changes:
- forbid to overwrite secrets of other users
- add some logs of success
- add validation on code (length 50)
- use same limiter for POST requests
2026-08-17 18:11:43 +03:00

112 lines
4.0 KiB
Markdown

# CodeVault
A small HTTP service that stores string values under access codes: write a
value with `setValue` under a code, later retrieve it with `getValue` using
that code. Basic Auth protects writes; reads are open but rate-limited by
failed-lookup count per client IP to slow down code guessing.
## Features
- `POST /api/v1/setValue` — store a value under a code (Basic Auth required).
- `POST /api/v1/getValue` — retrieve a value by code (public, rate-limited).
- Interactive API docs at `/api` (Swagger UI, embedded assets — no CDN).
- Prometheus metrics for HTTP requests and business events (successful/failed
gets and sets).
- OpenTelemetry logging, with optional OTLP export.
- SQLite storage (pure Go driver, no CGO).
- Configurable trusted proxies so client IPs are resolved correctly behind a
reverse proxy (e.g. nginx).
## Running
### Locally
```sh
go build
./codevault config-example ./config.yaml # write a starter config
./codevault add-user --db-path ./codevault.db --login admin # prompts for a password
./codevault run --config ./config.yaml
```
Or via the Makefile: `make build`, `make config-example`, `make add-user`,
`make run`.
### Docker
```sh
cp docker-compose.yaml.example docker-compose.yaml
go run . config-example ./config.yaml # or hand-write one, see Configuration below
docker compose up -d --build
docker compose exec codevault ./codevault add-user --db-path /app/data/codevault.db --login admin
```
The compose file mounts `config.yaml` read-only and keeps the SQLite database
in a named volume (`codevault-data`). Edit `server.trusted_proxies` in your
`config.yaml` to match the proxy/network actually in front of the container
(gin needs IPs/CIDRs, not hostnames).
## Configuration
`config-example` writes a documented starting point. Key sections:
```yaml
environment: development # development | production
server:
address: :8080
trusted_proxies: # IPs/CIDRs allowed to set X-Forwarded-For / X-Real-IP
- 172.16.0.0/12 # empty/omitted = trust nothing, use the raw remote address
database:
path: ./codevault.db
rate_limit:
max_failures: 10 # failed getValue lookups per IP before 404/401-ing get/post requests
window: 1m0s # sliding window for max_failures
observability:
logging:
stderr: INFO # DEBUG|INFO|WARNING|ERROR|PANIC|FATAL, empty disables
files:
INFO: ./info.log # per-level log files, optional
exporter: # optional OTLP log export
level: INFO
endpoint: http://127.0.0.1:4317/v1/logs
transport: grpc # grpc | http
metrics:
host: 127.0.0.1
port: 9092 # Prometheus /metrics endpoint
```
## API
Full OpenAPI spec: [internal/api/openapi.yaml](internal/api/openapi.yaml).
When the server is running, browse it interactively at `/api`, or fetch the
raw spec from `/api/openapi.json`.
- `POST /api/v1/getValue` `{"code": "..."}` → `200 {"value": "..."}` /
`404` (not found or rate-limited) / `400` (bad body).
- `POST /api/v1/setValue` `{"code": "...", "value": "..."}` (Basic Auth) →
`204` / `400` (bad body) / `401` (bad credentials or rate-limited) / '403' (owned by other user).
## Metrics
Exposed on `http://<metrics.host>:<metrics.port>/metrics`:
- `http_requests_total`, `http_request_duration_seconds` — generic per-route
HTTP metrics.
- `codevault_get_value_success_total{code}` — successful getValue lookups, by
code.
- `codevault_get_value_failed_total{reason}` — failed lookups, `reason` is
`not_found` or `rate_limited`.
- `codevault_set_value_success_total{user}` — successful setValue writes, by
authenticated login.
- `codevault_set_value_failed_total{reason}` — failed writes, `reason` is
`bad_request` or `unauthorized`.
## Development
```sh
make build # go build
make lint # golangci-lint
make generate # regenerate internal/api from openapi.yaml (oapi-codegen)
make test # go test ./...
make docker-build
```