claude skills
This commit is contained in:
parent
94bf5d94b8
commit
9bbff7b016
40 changed files with 4072 additions and 34 deletions
61
.kiro/steering/security.md
Normal file
61
.kiro/steering/security.md
Normal file
|
|
@ -0,0 +1,61 @@
|
|||
# Security Standards
|
||||
|
||||
## Philosophy
|
||||
|
||||
Defense in depth, least privilege, fail closed. Authentication verifies *who*; authorization verifies *what they can do*. Centralize both — never duplicate permission checks across handlers.
|
||||
|
||||
## RBAC Enforcement
|
||||
|
||||
All protected routes use `RequirePermission` middleware attached at registration time:
|
||||
|
||||
```go
|
||||
// In router/routers.go
|
||||
hostsGroup.GET("", RequirePermission("host:view"), handler)
|
||||
hostsGroup.POST("/control", RequirePermission("host:control"), handler)
|
||||
```
|
||||
|
||||
`RequirePermission` in `controllers/rbac_check.go` resolves the user from the JWT, looks up their effective permissions (including inherited role permissions), and aborts with 403 if the required permission is absent.
|
||||
|
||||
**cluster_admin** bypasses all permission checks via early return — do not add new bypass paths outside this single mechanism.
|
||||
|
||||
## Permission String Format
|
||||
|
||||
`"action:scope"` — e.g., `"job:submit"`, `"host:view"`, `"queue:manage"`.
|
||||
|
||||
Scopes: `all` (unrestricted), `self` (own resources), `cluster`, `hostgroup`, `self_ug`, `self_hg`.
|
||||
|
||||
Permissions are defined in `config/rbac.yaml`. Roles support inheritance via `includes:` — resolution is recursive. Add new permissions to the YAML first, then wire them onto routes.
|
||||
|
||||
## JWT Authentication
|
||||
|
||||
Token flow:
|
||||
1. `POST /auth/logon` → validates credentials via configured auth backend → issues JWT with `{username, IP, expiry}` claims
|
||||
2. Every subsequent request: `Authorization: Bearer <token>` header
|
||||
3. `middleware/validatehandler.go` strips the prefix, parses with golang-jwt, **validates the IP claim against the request IP**
|
||||
|
||||
IP-bound tokens prevent token theft across network boundaries. Do not remove the IP validation.
|
||||
|
||||
Token secret is loaded from `config/auth.yaml` at startup. It must never appear in source code or logs.
|
||||
|
||||
## Auth Backends
|
||||
|
||||
Backend selection is controlled by `config/auth.yaml`. Supported: `configfile`, `ldap`, `oauth2`, `pam`. All backends implement the same interface — adding a new backend means implementing that interface, not modifying middleware.
|
||||
|
||||
## Input Validation
|
||||
|
||||
Validate at the API boundary inside `preCheck{Resource}Request()` helpers — before any service or store access. Return 400 with a clear message on validation failure. Do not pass unvalidated input to downstream layers.
|
||||
|
||||
## Secrets
|
||||
|
||||
- JWT secret key: `config/auth.yaml` (file-system protected, chmod 0600)
|
||||
- LDAP bind credentials: `config/auth.yaml`
|
||||
- **Never log** tokens, passwords, secret keys, or full request bodies containing credentials
|
||||
- Validate all required config at startup; fail fast with a clear error if missing
|
||||
|
||||
## Rate Limiting and IP Whitelist
|
||||
|
||||
Rate limiting (`middleware/rate_limit.go`) and IP whitelist (`middleware/ip_whitelist.go`) are applied before JWT validation in the middleware chain. They use `ctx.ClientIP()` and abort with 429 / 403 respectively. Both are configured in `config/` YAML — do not hardcode thresholds.
|
||||
|
||||
## Transport
|
||||
|
||||
All daemon-to-daemon communication is over TCP. Production deployments add TLS at the network layer (not handled in application code). The WAL and replication wire format uses Cap'n Proto — schema files in `src/schema/`. Do not add unvalidated deserialization paths for external input.
|
||||
Loading…
Add table
Add a link
Reference in a new issue