Add unit tests for SBOM ingestion and transformation
Some checks failed
Docs CI / lint-and-preview (push) Has been cancelled

- Implement `SbomIngestServiceCollectionExtensionsTests` to verify the SBOM ingestion pipeline exports snapshots correctly.
- Create `SbomIngestTransformerTests` to ensure the transformation produces expected nodes and edges, including deduplication of license nodes and normalization of timestamps.
- Add `SbomSnapshotExporterTests` to test the export functionality for manifest, adjacency, nodes, and edges.
- Introduce `VexOverlayTransformerTests` to validate the transformation of VEX nodes and edges.
- Set up project file for the test project with necessary dependencies and configurations.
- Include JSON fixture files for testing purposes.
This commit is contained in:
master
2025-11-04 07:49:39 +02:00
parent f72c5c513a
commit 2eb6852d34
491 changed files with 39445 additions and 3917 deletions

View File

@@ -1,9 +1,20 @@
# RFC: StellaOps.Authority.Plugin.Ldap
**Status:** Draft for review by Auth Guild, Security Guild, DevEx (2025-10-10)
**Status:** Accepted Auth Guild, Security Guild, DevEx Docs sign-off (2025-11-03)
**Authors:** Plugin Team 4 (Auth Libraries & Identity Providers)
**Related initiatives:** PLG7 backlog, CORE5 event handlers, DOC4 developer guide
> Review log captured in `docs/notes/2025-11-03-authority-plugin-ldap-review.md`. Decisions below reflect consensus from Auth Guild, Security Guild, and DevEx Docs walkthroughs held on 2025-11-03.
## 0. Review Summary (2025-11-03)
- Confirmed plugin charter: deliver offline-friendly LDAP credential verification with deterministic caching and audit parity with the Standard plugin.
- Resolved open questions:
- **Client provisioning audit trail:** plugin always mirrors credential lifecycle metadata (actor, timestamp, hashed secret reference) into Authoritys Mongo store even when LDAP writes succeed; directory writes remain optional and secrets never persist locally.
- **Mutual TLS support:** LDAPS client certificates are required for regulated installations; configuration gains optional client certificate bindings with secret-provider integration and deterministic trust-store selection.
- **Group-to-role mapping:** mappings accept static DN dictionaries and deterministic `regex` matchers; regex captures project to canonical roles via substitution (documented contract for policy automation).
- Follow-up implementation issues filed in `StellaOps.Authority.Plugin.Standard/TASKS.md` (see Section 11) to track scaffolding, mutual TLS enablement, audit mirror, and mapping enhancements.
## 1. Problem Statement
Many on-prem StellaOps deployments rely on existing LDAP/Active Directory domains for workforce identity. The current Standard Mongo-backed plugin requires duplicating users and secrets, which increases operational overhead and violates corporate policy in some regulated environments. We need a sovereign, offline-friendly LDAP plugin that:
@@ -51,6 +62,13 @@ connection:
port: 636
useStartTls: false
validateCertificates: true
clientCertificate:
pfxPath: "file:/etc/stellaops/certs/ldap-client.pfx"
passwordSecret: "file:/etc/stellaops/secrets/ldap-client-pfx.txt"
sendChain: true
trustStore:
mode: "system" # system | bundle
bundlePath: "file:/etc/stellaops/trust/ldap-root.pem"
bindDn: "cn=stellaops-bind,ou=service,dc=example,dc=internal"
bindPasswordSecret: "file:/etc/stellaops/secrets/ldap-bind.txt"
searchBase: "dc=example,dc=internal"
@@ -58,6 +76,7 @@ connection:
userDnFormat: "uid={username},ou=people,dc=example,dc=internal" # optional template
security:
requireTls: true
allowInsecureWithEnvToggle: false # requires STELLAOPS_LDAP_ALLOW_INSECURE=true
allowedCipherSuites: [] # optional allow-list
referralChasing: false
lockout:
@@ -68,6 +87,9 @@ claims:
groupToRoleMap:
"cn=stellaops-admins,ou=groups,dc=example,dc=internal": "operators"
"cn=stellaops-read,ou=groups,dc=example,dc=internal": "auditors"
regexMappings:
- pattern: "^cn=stellaops-(?P<role>[a-z-]+),ou=groups,dc=example,dc=internal$"
roleFormat: "{role}" # yields operators/investigate/etc.
extraAttributes:
displayName: "displayName"
email: "mail"
@@ -75,6 +97,9 @@ clientProvisioning:
enabled: false
containerDn: "ou=service,dc=example,dc=internal"
secretAttribute: "userPassword"
auditMirror:
enabled: true
collectionName: "ldap_client_provisioning"
health:
probeIntervalSeconds: 60
timeoutSeconds: 5
@@ -83,43 +108,47 @@ health:
## 7. Capability Mapping
| Capability | Implementation Notes |
|------------|---------------------|
| `password` | Bind-as-user validation with Authority lockout integration. Mandatory. |
| `clientProvisioning` | Optional; when enabled, creates/updates LDAP entries for machine clients or stores metadata in Mongo if directory writes are disabled. |
| `bootstrap` | Exposed only when bootstrap manifest provides service account credentials AND directory write permissions are confirmed during startup. |
| `password` | Bind-as-user validation with Authority lockout integration. Mandatory. Requires TLS and optionally client certificate binding per regulated install posture. |
| `clientProvisioning` | Optional; when enabled, creates/updates LDAP entries for machine clients **and** mirrors lifecycle metadata into Mongo for audit parity. |
| `bootstrap` | Exposed only when bootstrap manifest provides service account credentials AND directory write permissions are confirmed during startup; always records audit mirror entries. |
| `mfa` | Not supported in MVP. Future iteration may integrate TOTP attributes or external MFA providers. |
## 8. Operational Considerations
- **Offline cache:** provide optional Mongo cache for group membership to keep `/ready` responsive if LDAP is temporarily unreachable. Cache entries must include TTL and invalidation hooks.
- **Secrets management:** accept `file:` and environment variable references; integrate with existing `StellaOps.Configuration` secret providers.
- **Mutual TLS & trust anchors:** support client certificate authentication with deterministic trust-store selection (`system` vs bundled file) to satisfy regulated deployments; surface validation outcomes via health endpoints.
- **Audit mirror:** write deterministic Mongo records capturing provisioning operations (actor, LDAP DN, operation type, hashed secret reference) to align with Authority audit policy even when LDAP is authoritative.
- **Observability:** emit structured logs with event IDs (`LDAP_BIND_START`, `LDAP_BIND_FAILURE`, `LDAP_GROUP_LOOKUP`), counters for success/failure, and latency histograms.
- **Throttling:** reuse Authority rate-limiting middleware; add per-connection throttles to avoid saturating directory servers during brute-force attacks.
## 9. Security & Compliance
- Enforce TLS (`ldaps://` or STARTTLS) by default. Provide explicit `allowInsecure` flag gated behind environment variable for lab/testing only.
- Support optional mutual TLS (client cert authentication) with secret-backed PFX loader and deterministic trust bundle selection.
- Support password hash migration by detecting directory lockout attributes and surfacing `RequiresPasswordReset` when policies demand changes.
- Log distinguished names only at `Debug` level to avoid leaking sensitive structure in default logs.
- Coordinate with Security Guild for penetration testing before GA; incorporate audit log entries for bind attempts and provisioning changes.
## 10. Testing Strategy
- **Unit tests:** mock LDAP connections to validate DN formatting, error mapping, and capability negotiation.
- **Integration tests:** run against an ephemeral OpenLDAP container (seeded via LDIF fixtures) within CI. Include offline cache regression (disconnect LDAP mid-test).
- **Integration tests:** run against an ephemeral OpenLDAP container (seeded via LDIF fixtures) within CI. Include mutual TLS handshake verification (valid/expired certs) and offline cache regression (disconnect LDAP mid-test).
- **Determinism tests:** feed identical LDIF snapshots and configuration to ensure output tokens/claims remain stable across runs.
- **Smoke tests:** `dotnet test` harness plus manual `dotnet run` scenario verifying `/token` password grants and `/internal/users` bootstrap with LDAP-backed store.
- **Smoke tests:** `dotnet test` harness plus manual `dotnet run` scenario verifying `/token` password grants, `/internal/users` bootstrap with LDAP-backed store, and Mongo audit mirror entries.
## 11. Implementation Plan
1. Scaffold `StellaOps.Authority.Plugin.Ldap` project + tests (net10.0, `<IsAuthorityPlugin>` true).
2. Implement configuration options + validation (mirroring Standard plugin guardrails).
3. Build connection factory + credential store with bind logic.
4. Implement claims enricher and optional cache layer.
5. Add client provisioning store (optional) with toggles for read-only deployments.
6. Wire bootstrapper to validate connectivity/permissions and record findings in startup logs.
7. Extend developer guide with LDAP specifics (post-RFC acceptance).
8. Update Docs and TODO trackers; produce release notes entry once merged.
1. Scaffold `StellaOps.Authority.Plugin.Ldap` project + companion test project (net10.0, `<IsAuthorityPlugin>` true).
2. Implement configuration binding/validation, including secret-backed client certificate + trust-store options and `allowInsecureWithEnvToggle`.
3. Build connection factory + credential store with bind logic, TLS enforcement, and deterministic retry policies.
4. Implement claims enricher with regex mapping support and optional Mongo-backed cache layer.
5. Add client provisioning store with LDAP write toggles and Mongo audit mirror (`ldap_client_provisioning` collection).
6. Wire health checks, telemetry, and structured audit events (bind attempts, provisioning, cache fallbacks).
7. Deliver bootstrap validation that inspects directory permissions and logs deterministic capability summary.
8. Extend developer guide and samples with LDAP configuration guidance; include mutual TLS and regex mapping examples.
9. Update docs/TASKS trackers and release notes entry; ensure CI coverage (unit, integration with OpenLDAP, determinism, smoke tests).
## 12. Open Questions
- Should client provisioning default to storing metadata in Mongo even when LDAP writes succeed (to preserve audit history)?
- Do we require LDAPS mutual TLS support (client certificates) for regulated environments? If yes, need to extend configuration schema.
- How will we map LDAP groups to Authority scopes/roles when names differ significantly? Consider supporting regex or mapping scripts.
## 12. Resolved Questions
- **Audit mirror:** Client provisioning always persists lifecycle metadata in Mongo for audit parity; LDAP remains the credential source of truth.
- **Mutual TLS:** Plugin must support optional client certificate authentication with secret-backed key material and deterministic trust-store selection.
- **Group mapping:** Provide deterministic regex mapping support to translate directory DNs into Authority roles/scopes without custom scripts.
## 13. Timeline (Tentative)
- **Week 1:** RFC review & sign-off.
@@ -128,9 +157,9 @@ health:
- **Week 5:** Security review, release candidate packaging.
## 14. Approval
- **Auth Guild Lead:** _TBD_
- **Security Guild Representative:** _TBD_
- **DevEx Docs:** _TBD_
- **Auth Guild Lead:** ✅ Approved 2025-11-03 (see review log).
- **Security Guild Representative:** ✅ Approved 2025-11-03 (see review log).
- **DevEx Docs:** ✅ Approved 2025-11-03 (see review log).
---
Please add comments inline or via PR review. Once approved, track execution under PLG7.