Initial commit (history squashed)
	
		
			
	
		
	
	
		
	
		
			Some checks failed
		
		
	
	
		
			
				
	
				Build Test Deploy / authority-container (push) Has been cancelled
				
			
		
			
				
	
				Build Test Deploy / docs (push) Has been cancelled
				
			
		
			
				
	
				Build Test Deploy / deploy (push) Has been cancelled
				
			
		
			
				
	
				Build Test Deploy / build-test (push) Has been cancelled
				
			
		
			
				
	
				Docs CI / lint-and-preview (push) Has been cancelled
				
			
		
		
	
	
				
					
				
			
		
			Some checks failed
		
		
	
	Build Test Deploy / authority-container (push) Has been cancelled
				
			Build Test Deploy / docs (push) Has been cancelled
				
			Build Test Deploy / deploy (push) Has been cancelled
				
			Build Test Deploy / build-test (push) Has been cancelled
				
			Docs CI / lint-and-preview (push) Has been cancelled
				
			This commit is contained in:
		
							
								
								
									
										21
									
								
								src/StellaOps.Cryptography/AGENTS.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										21
									
								
								src/StellaOps.Cryptography/AGENTS.md
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,21 @@ | ||||
| # Team 8 — Security Guild (Authority & Shared Crypto) | ||||
|  | ||||
| ## Role | ||||
|  | ||||
| Team 8 owns the end-to-end security posture for StellaOps Authority and its consumers. That includes password hashing policy, audit/event hygiene, rate-limit & lockout rules, revocation distribution, and sovereign cryptography abstractions that allow alternative algorithm suites (e.g., GOST) without touching feature code. | ||||
|  | ||||
| ## Operational Boundaries | ||||
|  | ||||
| - Primary workspace: `src/StellaOps.Cryptography`, `src/StellaOps.Authority.Plugin.Standard`, `src/StellaOps.Authority.Storage.Mongo`, and Authority host (`src/StellaOps.Authority/StellaOps.Authority`).   | ||||
| - Coordinate cross-module changes via TASKS.md updates and PR descriptions.   | ||||
| - Never bypass deterministic behaviour (sorted keys, stable timestamps).   | ||||
| - Tests live alongside owning projects (`*.Tests`). Extend goldens instead of rewriting. | ||||
|  | ||||
| ## Expectations | ||||
|  | ||||
| - Default to Argon2id (Konscious) for password hashing; PBKDF2 only for legacy verification with transparent rehash on success.   | ||||
| - Emit structured security events with minimal PII and clear correlation IDs.   | ||||
| - Rate-limit `/token` and bootstrap endpoints once CORE8 hooks are available.   | ||||
| - Deliver offline revocation bundles signed with detached JWS and provide a verification script.   | ||||
| - Maintain `docs/security/authority-threat-model.md` and ensure mitigations are tracked.   | ||||
| - All crypto consumption flows through `StellaOps.Cryptography` abstractions to enable sovereign crypto providers. | ||||
							
								
								
									
										44
									
								
								src/StellaOps.Cryptography/CryptoProvider.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										44
									
								
								src/StellaOps.Cryptography/CryptoProvider.cs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,44 @@ | ||||
| using System.Collections.Generic; | ||||
|  | ||||
| namespace StellaOps.Cryptography; | ||||
|  | ||||
| /// <summary> | ||||
| /// High-level cryptographic capabilities supported by StellaOps providers. | ||||
| /// </summary> | ||||
| public enum CryptoCapability | ||||
| { | ||||
|     PasswordHashing, | ||||
|     Signing, | ||||
|     Verification, | ||||
|     SymmetricEncryption, | ||||
|     KeyDerivation | ||||
| } | ||||
|  | ||||
| /// <summary> | ||||
| /// Identifies a stored key or certificate handle. | ||||
| /// </summary> | ||||
| public sealed record CryptoKeyReference(string KeyId, string? ProviderHint = null); | ||||
|  | ||||
| /// <summary> | ||||
| /// Contract implemented by crypto providers (BCL, CryptoPro, OpenSSL, etc.). | ||||
| /// </summary> | ||||
| public interface ICryptoProvider | ||||
| { | ||||
|     string Name { get; } | ||||
|  | ||||
|     bool Supports(CryptoCapability capability, string algorithmId); | ||||
|  | ||||
|     IPasswordHasher GetPasswordHasher(string algorithmId); | ||||
| } | ||||
|  | ||||
| /// <summary> | ||||
| /// Registry managing provider discovery and policy selection. | ||||
| /// </summary> | ||||
| public interface ICryptoProviderRegistry | ||||
| { | ||||
|     IReadOnlyCollection<ICryptoProvider> Providers { get; } | ||||
|  | ||||
|     bool TryResolve(string preferredProvider, out ICryptoProvider provider); | ||||
|  | ||||
|     ICryptoProvider ResolveOrThrow(CryptoCapability capability, string algorithmId); | ||||
| } | ||||
							
								
								
									
										81
									
								
								src/StellaOps.Cryptography/PasswordHashing.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										81
									
								
								src/StellaOps.Cryptography/PasswordHashing.cs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,81 @@ | ||||
| using System; | ||||
|  | ||||
| namespace StellaOps.Cryptography; | ||||
|  | ||||
| /// <summary> | ||||
| /// Supported password hashing algorithms. | ||||
| /// </summary> | ||||
| public enum PasswordHashAlgorithm | ||||
| { | ||||
|     Argon2id, | ||||
|     Pbkdf2 | ||||
| } | ||||
|  | ||||
| /// <summary> | ||||
| /// Options describing password hashing requirements. | ||||
| /// Values follow OWASP baseline guidance by default. | ||||
| /// </summary> | ||||
| public sealed record PasswordHashOptions | ||||
| { | ||||
|     /// <summary> | ||||
|     /// Algorithm to use when hashing new passwords. | ||||
|     /// </summary> | ||||
|     public PasswordHashAlgorithm Algorithm { get; init; } = PasswordHashAlgorithm.Argon2id; | ||||
|  | ||||
|     /// <summary> | ||||
|     /// Memory cost in KiB (default 19 MiB). | ||||
|     /// </summary> | ||||
|     public int MemorySizeInKib { get; init; } = 19 * 1024; | ||||
|  | ||||
|     /// <summary> | ||||
|     /// Iteration count / time cost. | ||||
|     /// </summary> | ||||
|     public int Iterations { get; init; } = 2; | ||||
|  | ||||
|     /// <summary> | ||||
|     /// Parallelism / degree of concurrency. | ||||
|     /// </summary> | ||||
|     public int Parallelism { get; init; } = 1; | ||||
|  | ||||
|     /// <summary> | ||||
|     /// Validates the option values and throws when invalid. | ||||
|     /// </summary> | ||||
|     public void Validate() | ||||
|     { | ||||
|         if (MemorySizeInKib <= 0) | ||||
|         { | ||||
|             throw new InvalidOperationException("Password hashing memory cost must be greater than zero."); | ||||
|         } | ||||
|  | ||||
|         if (Iterations <= 0) | ||||
|         { | ||||
|             throw new InvalidOperationException("Password hashing iteration count must be greater than zero."); | ||||
|         } | ||||
|  | ||||
|         if (Parallelism <= 0) | ||||
|         { | ||||
|             throw new InvalidOperationException("Password hashing parallelism must be greater than zero."); | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | ||||
| /// <summary> | ||||
| /// Abstraction for password hashing implementations. | ||||
| /// </summary> | ||||
| public interface IPasswordHasher | ||||
| { | ||||
|     /// <summary> | ||||
|     /// Produces an encoded hash for the supplied password. | ||||
|     /// </summary> | ||||
|     string Hash(string password, PasswordHashOptions options); | ||||
|  | ||||
|     /// <summary> | ||||
|     /// Verifies the supplied password against a stored hash. | ||||
|     /// </summary> | ||||
|     bool Verify(string password, string encodedHash); | ||||
|  | ||||
|     /// <summary> | ||||
|     /// Detects when an existing encoded hash no longer satisfies the desired options. | ||||
|     /// </summary> | ||||
|     bool NeedsRehash(string encodedHash, PasswordHashOptions desired); | ||||
| } | ||||
							
								
								
									
										9
									
								
								src/StellaOps.Cryptography/StellaOps.Cryptography.csproj
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								src/StellaOps.Cryptography/StellaOps.Cryptography.csproj
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,9 @@ | ||||
| <Project Sdk="Microsoft.NET.Sdk"> | ||||
|   <PropertyGroup> | ||||
|     <TargetFramework>net10.0</TargetFramework> | ||||
|     <LangVersion>preview</LangVersion> | ||||
|     <ImplicitUsings>enable</ImplicitUsings> | ||||
|     <Nullable>enable</Nullable> | ||||
|     <TreatWarningsAsErrors>true</TreatWarningsAsErrors> | ||||
|   </PropertyGroup> | ||||
| </Project> | ||||
							
								
								
									
										25
									
								
								src/StellaOps.Cryptography/TASKS.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										25
									
								
								src/StellaOps.Cryptography/TASKS.md
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,25 @@ | ||||
| # Team 8 — Security Guild Task Board (UTC 2025-10-10) | ||||
|  | ||||
| | ID | Status | Owner | Description | Dependencies | Exit Criteria | | ||||
| |----|--------|-------|-------------|--------------|---------------| | ||||
| | SEC1.A | TODO | Security Guild | Introduce `Argon2idPasswordHasher` backed by Konscious defaults. Wire options into `StandardPluginOptions` (`PasswordHashOptions`) and `StellaOpsAuthorityOptions.Security.PasswordHashing`. | PLG3, CORE3 | ✅ Hashes emit PHC string `$argon2id$v=19$m=19456,t=2,p=1$...`; ✅ `NeedsRehash` promotes PBKDF2 → Argon2; ✅ Integration tests cover tamper, legacy rehash, perf p95 < 250 ms. | | ||||
| | SEC1.B | TODO | Security Guild | Add compile-time switch to enable libsodium/Core variants later (`STELLAOPS_CRYPTO_SODIUM`). Document build variable. | SEC1.A | ✅ Conditional compilation path compiles; ✅ README snippet in `docs/security/password-hashing.md`. | | ||||
| | SEC2.A | TODO | Security Guild + Core | Define audit event contract (`AuthEventRecord`) with subject/client/scope/IP/outcome/correlationId and PII tags. | CORE5–CORE7 | ✅ Contract shipped in `StellaOps.Cryptography` (or shared abstractions); ✅ Docs in `docs/security/audit-events.md`. | | ||||
| | SEC2.B | TODO | Security Guild | Emit audit records from OpenIddict handlers (password + client creds) and bootstrap APIs. Persist via `IAuthorityLoginAttemptStore`. | SEC2.A | ✅ Tests assert three flows (success/failure/lockout); ✅ Serilog output contains correlationId + PII tagging; ✅ Mongo store holds summary rows. | | ||||
| | SEC3.A | BLOCKED (CORE8) | Security Guild + Core | Configure ASP.NET rate limiter (`AddRateLimiter`) with fixed-window policy keyed by IP + `client_id`. Apply to `/token` and `/internal/*`. | CORE8 completion | ✅ Middleware active; ✅ Configurable limits via options; ✅ Integration test hits 429. | | ||||
| | SEC3.B | TODO | Security Guild | Document lockout + rate-limit tuning guidance and escalation thresholds. | SEC3.A | ✅ Section in `docs/security/rate-limits.md`; ✅ Includes SOC alert recommendations. | | ||||
| | SEC4.A | TODO | Security Guild + DevOps | Define revocation JSON schema (`revocation_bundle.schema.json`) and detached JWS workflow. | CORE9, OPS3 | ✅ Schema + sample committed; ✅ CLI command `stellaops auth revoke export` scaffolded with acceptance tests; ✅ Verification script + docs. | | ||||
| | SEC4.B | TODO | Security Guild | Integrate signing keys with crypto provider abstraction (initially ES256 via BCL). | SEC4.A, D5 | ✅ `ICryptoProvider.GetSigner` stub + default BCL signer; ✅ Unit tests verifying signature roundtrip. | | ||||
| | SEC5.A | TODO | Security Guild | Author STRIDE threat model (`docs/security/authority-threat-model.md`) covering token, bootstrap, revocation, CLI, plugin surfaces. | All SEC1–SEC4 in progress | ✅ DFDs + trust boundaries drawn; ✅ Risk table with owners/actions; ✅ Follow-up backlog issues created. | | ||||
| | D5.A | TODO | Security Guild | Flesh out `StellaOps.Cryptography` provider registry, policy, and DI helpers enabling sovereign crypto selection. | SEC1.A, SEC4.B | ✅ `ICryptoProviderRegistry` implementation with provider selection rules; ✅ `StellaOps.Cryptography.DependencyInjection` extensions; ✅ Tests covering fallback ordering. | | ||||
|  | ||||
| ## Notes | ||||
| - Target Argon2 parameters follow OWASP Cheat Sheet (memory ≈ 19 MiB, iterations 2, parallelism 1). Allow overrides via configuration. | ||||
| - When CORE8 lands, pair with Team 2 to expose request context information required by the rate limiter (client_id enrichment). | ||||
| - Revocation bundle must be consumable offline; include issue timestamp, signing key metadata, and reasons. | ||||
| - All crypto usage in Authority code should funnel through the new abstractions (`ICryptoProvider`), enabling future CryptoPro/OpenSSL providers. | ||||
|  | ||||
| ## Done Definition | ||||
| - Code merges include unit/integration tests and documentation updates. | ||||
| - `TASKS.md` status transitions (TODO → DOING → DONE/BLOCKED) must happen in the same PR as the work. | ||||
| - Prior to marking DONE: run `dotnet test` for touched solutions and attach excerpt to PR description. | ||||
		Reference in New Issue
	
	Block a user