@keelcore/standards 0.9.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +99 -0
- package/governance/ai/conduct.md +66 -0
- package/governance/api-management.md +185 -0
- package/governance/arb.md +110 -0
- package/governance/bash.md +147 -0
- package/governance/ci.md +496 -0
- package/governance/coding.md +156 -0
- package/governance/observability.md +158 -0
- package/governance/platform.md +167 -0
- package/governance/release-policy.md +171 -0
- package/governance/runtime.md +165 -0
- package/governance/security.md +149 -0
- package/governance/testing.md +100 -0
- package/package.json +27 -0
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
# Security Standards
|
|
2
|
+
|
|
3
|
+
These rules govern identity and access management, encryption, key management, and data handling.
|
|
4
|
+
They are non-negotiable unless explicitly superseded by a signed ADR.
|
|
5
|
+
|
|
6
|
+
**Maturity:** Required
|
|
7
|
+
**Version:** 1.0.0
|
|
8
|
+
**Last Reviewed:** 2026-03-09
|
|
9
|
+
|
|
10
|
+
## Identity and Access Management
|
|
11
|
+
|
|
12
|
+
### Federated Authentication
|
|
13
|
+
|
|
14
|
+
1. All human-facing authentication uses a federated identity provider (IdP) via OIDC or SAML 2.0.
|
|
15
|
+
Local username/password stores are prohibited for production systems.
|
|
16
|
+
2. The approved AuthN vendor(s) are documented in the internal vendor registry. No additional identity
|
|
17
|
+
providers are introduced without ARB approval and a security review.
|
|
18
|
+
3. Multi-factor authentication (MFA) is required for all human accounts. Phishing-resistant MFA
|
|
19
|
+
(FIDO2/WebAuthn) is required for privileged and production access.
|
|
20
|
+
|
|
21
|
+
### Workload Identity
|
|
22
|
+
|
|
23
|
+
4. Service-to-service authentication uses SPIFFE/SPIRE (or an equivalent SVID-based workload identity
|
|
24
|
+
system). Static shared secrets for service identity are prohibited.
|
|
25
|
+
5. SPIFFE Verifiable Identity Documents (SVIDs) are issued with a maximum 24-hour TTL and rotated
|
|
26
|
+
automatically.
|
|
27
|
+
6. JWT-based identity is acceptable for external API integrations where SPIFFE is not available.
|
|
28
|
+
JWTs must be signed (RS256 or ES256 minimum) and have an explicit `exp` claim. Unsigned or
|
|
29
|
+
HS256-signed JWTs are prohibited in production.
|
|
30
|
+
|
|
31
|
+
### Token Lifecycle and Revocation
|
|
32
|
+
|
|
33
|
+
7. Access tokens have a maximum lifetime of 15 minutes. Refresh tokens have a maximum lifetime of
|
|
34
|
+
8 hours for human sessions; service refresh tokens do not exist (workload identity handles renewal).
|
|
35
|
+
8. Token revocation is effective within 60 seconds. Caches that hold token validation results must
|
|
36
|
+
honor the revocation TTL.
|
|
37
|
+
9. Refresh tokens are single-use and rotated on every use. Reuse of a refresh token triggers
|
|
38
|
+
immediate session termination and a security alert.
|
|
39
|
+
10. All issued tokens are logged with: issuer, subject, audience, `jti`, issued-at, and expiry.
|
|
40
|
+
|
|
41
|
+
## Authorization
|
|
42
|
+
|
|
43
|
+
### Service-Level Routing AuthZ
|
|
44
|
+
|
|
45
|
+
11. API gateways and ingress controllers enforce coarse-grained authorization (service-to-service
|
|
46
|
+
trust boundaries) before traffic reaches application pods.
|
|
47
|
+
12. Services must not trust the caller's claimed identity from request headers alone; the identity
|
|
48
|
+
assertion must be cryptographically verified (mTLS client cert or verified JWT) by the mesh or
|
|
49
|
+
gateway layer.
|
|
50
|
+
|
|
51
|
+
### Role-Based Access Control (RBAC)
|
|
52
|
+
|
|
53
|
+
13. RBAC roles are defined at the minimum privilege required for each function. There are no
|
|
54
|
+
"superuser" roles in production except for documented break-glass accounts.
|
|
55
|
+
14. Role assignments are reviewed quarterly. Stale role assignments are revoked automatically after
|
|
56
|
+
90 days without reaffirmation.
|
|
57
|
+
15. Role definitions and assignments are stored in version-controlled configuration. Manual UI-based
|
|
58
|
+
role grants that bypass version control are prohibited.
|
|
59
|
+
|
|
60
|
+
### Attribute-Based Access Control (ABAC)
|
|
61
|
+
|
|
62
|
+
16. Fine-grained access decisions (data-level, row-level) are implemented via ABAC policies in the
|
|
63
|
+
centralized policy engine (OPA or equivalent).
|
|
64
|
+
17. ABAC policies are co-located with the service that owns the resource. Cross-service policy
|
|
65
|
+
definitions require ARB approval.
|
|
66
|
+
|
|
67
|
+
### Centralized Policy Engine
|
|
68
|
+
|
|
69
|
+
18. The approved policy engine (OPA or equivalent) is the single source of truth for all
|
|
70
|
+
authorization decisions. Services must not implement ad-hoc authorization logic that duplicates
|
|
71
|
+
or overrides centralized policy.
|
|
72
|
+
19. Policies are version-controlled. Every policy change requires a review and an audit log entry.
|
|
73
|
+
20. The policy engine exposes a health endpoint; its unavailability must cause authorization
|
|
74
|
+
decisions to fail closed (deny), not fail open (permit).
|
|
75
|
+
|
|
76
|
+
### Policy Versioning and Rollback
|
|
77
|
+
|
|
78
|
+
21. Policies are tagged with a version identifier. The current version in force is queryable from
|
|
79
|
+
the policy engine.
|
|
80
|
+
22. Any policy change can be rolled back to the previous version within 5 minutes via the policy
|
|
81
|
+
engine's rollback mechanism.
|
|
82
|
+
|
|
83
|
+
### Delegated Permissions
|
|
84
|
+
|
|
85
|
+
23. Delegated admin domains (e.g., team-level RBAC management) are scoped to the team's namespace.
|
|
86
|
+
Cross-namespace privilege delegation requires ARB approval.
|
|
87
|
+
24. OAuth 2.0 delegated scopes must be explicitly documented per API. Broad wildcard scopes
|
|
88
|
+
(e.g., `*`, `admin`) are prohibited unless the API is itself an admin API.
|
|
89
|
+
|
|
90
|
+
## Encryption
|
|
91
|
+
|
|
92
|
+
### Encryption in Transit
|
|
93
|
+
|
|
94
|
+
25. All traffic between pods, nodes, and external systems is encrypted. Plaintext communication
|
|
95
|
+
inside the cluster is prohibited in staging and production.
|
|
96
|
+
26. Service-to-service encryption is enforced via mTLS at the service mesh layer.
|
|
97
|
+
27. Traffic to external APIs uses TLS 1.2 minimum; TLS 1.3 preferred. See `governance/platform.md`
|
|
98
|
+
for cipher suite requirements.
|
|
99
|
+
|
|
100
|
+
### Encryption at Rest
|
|
101
|
+
|
|
102
|
+
28. All persistent data stores (databases, object storage, message queues, caches) encrypt data
|
|
103
|
+
at rest using AES-256 or equivalent.
|
|
104
|
+
29. Encryption keys for data at rest are managed by the approved key management service (KMS)
|
|
105
|
+
and never stored alongside the data they protect.
|
|
106
|
+
30. Backup and snapshot data is encrypted with the same or stronger controls as primary data.
|
|
107
|
+
|
|
108
|
+
### Key Management
|
|
109
|
+
|
|
110
|
+
31. The approved KMS vendor(s) are documented in the internal vendor registry. Application-managed
|
|
111
|
+
key stores (manual key files, hardcoded keys) are prohibited.
|
|
112
|
+
32. Encryption keys are rotated on a defined schedule: symmetric keys every 90 days, asymmetric
|
|
113
|
+
keys every 12 months, unless a shorter rotation is required by compliance or incident response.
|
|
114
|
+
33. Key rotation is zero-downtime. Services must reload keys without restart.
|
|
115
|
+
|
|
116
|
+
### Formal Rapid Key Rotation
|
|
117
|
+
|
|
118
|
+
34. The platform must support emergency key rotation with an SLA of 5 minutes or less for the
|
|
119
|
+
entire network.
|
|
120
|
+
35. Services must reload encryption keys upon receiving a designated OS signal (e.g., SIGUSR1)
|
|
121
|
+
or a KMS-pushed notification, without process restart.
|
|
122
|
+
36. Key rotation events are logged in the audit log with: key ID, rotation trigger (scheduled or
|
|
123
|
+
emergency), actor, and timestamp.
|
|
124
|
+
37. Emergency key rotation is tested in staging at least quarterly. Results are documented.
|
|
125
|
+
|
|
126
|
+
## Data Classification and Handling
|
|
127
|
+
|
|
128
|
+
38. All data is classified at creation time as one of: `public`, `internal`, `confidential`,
|
|
129
|
+
or `restricted`. Classification is stored as metadata alongside the data.
|
|
130
|
+
39. `confidential` and `restricted` data must be encrypted at rest and in transit, accessed only
|
|
131
|
+
via authorized roles, and logged on every access.
|
|
132
|
+
40. `restricted` data (e.g., payment card data, health records) must also be isolated in dedicated
|
|
133
|
+
storage with network-level segmentation from general-purpose stores.
|
|
134
|
+
41. Data handling procedures for each classification level are documented in the internal data
|
|
135
|
+
handling policy. That policy is reviewed annually and after any significant breach or
|
|
136
|
+
compliance change.
|
|
137
|
+
|
|
138
|
+
## Do Not
|
|
139
|
+
|
|
140
|
+
- Use local username/password stores for production authentication.
|
|
141
|
+
- Use shared static secrets for service-to-service authentication.
|
|
142
|
+
- Issue unsigned or HS256-signed JWTs in production.
|
|
143
|
+
- Allow authorization to fail open when the policy engine is unavailable.
|
|
144
|
+
- Make ad-hoc role grants that bypass version-controlled configuration.
|
|
145
|
+
- Store encryption keys alongside the data they protect.
|
|
146
|
+
- Hardcode encryption keys or tokens in application code or config files.
|
|
147
|
+
- Perform key rotation that requires a service restart.
|
|
148
|
+
- Log, print, or expose key material at any log level.
|
|
149
|
+
- Allow `restricted` data in general-purpose storage.
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
# Testing Standards
|
|
2
|
+
|
|
3
|
+
These rules govern all test code and test infrastructure in this project. They are non-negotiable.
|
|
4
|
+
|
|
5
|
+
**Maturity:** Required
|
|
6
|
+
**Version:** 1.0.0
|
|
7
|
+
**Last Reviewed:** 2026-03-14
|
|
8
|
+
|
|
9
|
+
## Core Principle
|
|
10
|
+
|
|
11
|
+
Unit tests do not cross system boundaries.
|
|
12
|
+
|
|
13
|
+
A system boundary is anything that requires a network peer, an OS service, or an external process.
|
|
14
|
+
If a test needs one of those, it is an integration test and belongs in BATS, Compose, or a
|
|
15
|
+
cluster-level suite — not in a `_test.go` file.
|
|
16
|
+
|
|
17
|
+
## What Goes in Unit Tests
|
|
18
|
+
|
|
19
|
+
- Config parsing and validation (all fields, all error branches)
|
|
20
|
+
- Data transformations and serialization
|
|
21
|
+
- State machine transitions (circuit breaker, reload lifecycle)
|
|
22
|
+
- Middleware wiring and handler composition
|
|
23
|
+
- Error branches on bad or missing inputs
|
|
24
|
+
- Pure logic with no I/O
|
|
25
|
+
|
|
26
|
+
## What Goes in Integration Tests
|
|
27
|
+
|
|
28
|
+
- ACME end-to-end certificate issuance — use a real ACME test CA (e.g. pebble)
|
|
29
|
+
- OPA policy evaluation — use a real OPA process
|
|
30
|
+
- Remote logging sink reachability — real HTTP or syslog endpoint
|
|
31
|
+
- Upstream proxy behavior — real HTTP upstream server
|
|
32
|
+
- Syslog emission — real syslog daemon
|
|
33
|
+
- Compose and Kubernetes deployment smoke tests
|
|
34
|
+
|
|
35
|
+
## Real Tools Over Mocks
|
|
36
|
+
|
|
37
|
+
Do not mock external systems. Use real implementations in integration tests.
|
|
38
|
+
|
|
39
|
+
Mocks replicate the mock author's understanding of a contract at a point in time. When the real
|
|
40
|
+
system changes, mocks silently pass. Real tools catch contract drift.
|
|
41
|
+
|
|
42
|
+
Acceptable alternatives to real systems:
|
|
43
|
+
|
|
44
|
+
- In-process test servers (e.g. `httptest.NewServer`) for HTTP — acceptable in unit tests.
|
|
45
|
+
- Real test daemons (pebble, OPA, syslog) — required in integration tests.
|
|
46
|
+
- Never: mocked network peers, mocked OS services, mocked external processes.
|
|
47
|
+
|
|
48
|
+
## Test Suite Structure
|
|
49
|
+
|
|
50
|
+
Every project MUST define the following test layers. Names and Makefile targets are fixed.
|
|
51
|
+
|
|
52
|
+
| Layer | Makefile target | Scope | External deps |
|
|
53
|
+
|---|---|---|---|
|
|
54
|
+
| Unit | `make unit-test` | In-process logic; no system boundaries | None |
|
|
55
|
+
| Integration | `make integration-test` | Binary + real peers | Test daemons on PATH |
|
|
56
|
+
| Compose | `make test-compose` | Full stack via Docker Compose | Docker |
|
|
57
|
+
| Kubernetes | `make test-k8s` | Helm deploy + pod probes | kind / Docker |
|
|
58
|
+
|
|
59
|
+
## Test File Layout
|
|
60
|
+
|
|
61
|
+
- Unit tests: `_test.go` files co-located with the package under test.
|
|
62
|
+
- BATS integrity: `tests/integrity.bats` — runs against the built binary, not source.
|
|
63
|
+
- Compose tests: `tests/compose/` — topology + assertions.
|
|
64
|
+
- Fixtures: `tests/fixtures/` — static inputs; no generated artifacts committed.
|
|
65
|
+
- Generated test certs: `tests/fixtures/gen-certs.sh`; output gitignored.
|
|
66
|
+
|
|
67
|
+
## JUnit XML and Coverage
|
|
68
|
+
|
|
69
|
+
- Unit test runner MUST emit JUnit XML (`gotestsum --junitfile` or equivalent).
|
|
70
|
+
- Upload JUnit XML as a workflow artifact for test history and flake detection.
|
|
71
|
+
- Coverage profile MUST be produced on every unit test run.
|
|
72
|
+
- `make coverage` prints: total %, uncovered statement count, total statement count.
|
|
73
|
+
- `make ci-coverage-delta` compares PR head coverage against the merge-target base branch;
|
|
74
|
+
fails if coverage drops beyond the configured threshold.
|
|
75
|
+
|
|
76
|
+
## Test Modification Policy
|
|
77
|
+
|
|
78
|
+
Test files are protected. Do not modify test files without explicit prior authorization.
|
|
79
|
+
|
|
80
|
+
When a test fails, the correct response is to find and fix the root cause in production code —
|
|
81
|
+
not to adjust the test to pass. A failing test is a signal, not an obstacle.
|
|
82
|
+
|
|
83
|
+
Exceptions require explicit approval:
|
|
84
|
+
|
|
85
|
+
- The test itself contains a bug.
|
|
86
|
+
- The tested behavior was intentionally changed and the test must track the new contract.
|
|
87
|
+
- A new test is being added.
|
|
88
|
+
|
|
89
|
+
## FIPS Compatibility
|
|
90
|
+
|
|
91
|
+
Tests that use `InsecureSkipVerify`, self-signed certs via `httptest`, or non-FIPS algorithms
|
|
92
|
+
MUST be guarded with a FIPS skip:
|
|
93
|
+
|
|
94
|
+
```go
|
|
95
|
+
if os.Getenv("GOFIPS140") != "" {
|
|
96
|
+
t.Skip("skipping under FIPS")
|
|
97
|
+
}
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
Do not leave FIPS-incompatible tests unguarded; they will fail CI on FIPS builds.
|
package/package.json
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@keelcore/standards",
|
|
3
|
+
"version": "0.9.7",
|
|
4
|
+
"description": "Engineering standards for keelcore projects — coding, CI, and bash.",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"standards",
|
|
7
|
+
"engineering",
|
|
8
|
+
"ci",
|
|
9
|
+
"coding",
|
|
10
|
+
"ai"
|
|
11
|
+
],
|
|
12
|
+
"license": "MIT",
|
|
13
|
+
"repository": {
|
|
14
|
+
"type": "git",
|
|
15
|
+
"url": "https://github.com/keelcore/standards"
|
|
16
|
+
},
|
|
17
|
+
"files": [
|
|
18
|
+
"governance/"
|
|
19
|
+
],
|
|
20
|
+
"scripts": {
|
|
21
|
+
"prepublishOnly": "node -e \"require('fs').readdirSync('./governance').forEach(f => console.log('governance:', f))\"",
|
|
22
|
+
"lint:md": "markdownlint-cli2 \"**/*.md\" \"#node_modules\""
|
|
23
|
+
},
|
|
24
|
+
"devDependencies": {
|
|
25
|
+
"markdownlint-cli2": "^0.21.0"
|
|
26
|
+
}
|
|
27
|
+
}
|