Conversation
gtema
commented
Jun 13, 2026
Collaborator
- feat(core): add mapping engine provider scaffolding
- feat: Implement mapping-driver-raft and integration tests
- feat: Add enable/disable virtual user methods
- feat(mapping): ADR-0020 Phase 1
Add data model, provider traits, service layer, and mock for the unified mapping engine. Data model (core-types/mapping/): - DomainResolutionMode, IdentitySource - MappingRuleSet, MappingRuleSetCreate, MappingRuleSetUpdate, MappingRuleSetListParameters - MappingRule, MatchCriteria, MatchCondition, ClaimCondition, IdentityBinding - Authorization, GroupAssignment, GroupStrategy - VirtualUser, MatchResult, VirtualUserListParameters - RuleMutations, RuleMutation, RulePosition (imperative mutation types) - MappingProviderError with 8 variants Provider scaffolding (core/mapping/): - MappingApi trait with 8 methods sorted alphabetically - MappingBackend trait with 11 methods (adds CRUD for virtual users) - MappingService delegates all methods to backend driver - MappingProvider enum (Service/Mock) with full dispatch - MockMappingProvider via mockall, plus MappingHook stub Infrastructure wiring: - Config struct in config/mapping.rs with driver field (default: raft) - PluginManagerApi: get/register_mapping_backend - Provider struct: MappingProvider field, accessor, mock builder - KeystoneError::Mapping variant for error propagation - GroupRef struct in identity/group.rs
Add the Raft backend driver for the mapping provider with full CRUD support for rulesets and virtual user shadow records. Changes: - Create crates/mapping-driver-raft with MappingBackend implementation - Register driver in plugin_manager as "raft", add workspace dependency - Fix MappingBackend::create_ruleset signature: take MappingRuleSet instead of MappingRuleSetCreate so service layer can attach mapping_id and ruleset_version before storage - Add service-layer unit tests for create, delete, get, list, update, mutate_rules (including immutability checks and error cases) - Add 14 integration tests for ruleset CRUD, list filtering, and vuser get/delete under --profile raft - Add From<MappingRuleSetCreate> for MappingRuleSet and MappingRuleSet::with_update() in core-types - Exclude mapping tests from default nextest profile, document --profile raft in CONTRIBUTING.md Signed-off-by: Artem Goncharov <artem.goncharov@gmail.com>
Virtual user lifecycle need to be extended with dedicated methods for audit purpose.
Implement CAS-protected virtual user shadow registry upsert, CAS-on-delete, scope resolution, and the core authenticate_by_mapping pipeline for ADR-0020 Phase 1. Storage layer (openstack-keystone-distributed-storage): - Add StoreError::Conflict for concurrent modification races - State machine performs per-entry atomic batch: on CAS violation for any mutation, the entire entry batch is discarded (not individual mutations) - Add Mutation::CreateIfAbsent for atomic create-or-conflict semantics - Add expected_revision field to Mutation::Remove for CAS-protected deletes - Mock storage enforces CAS-on-remove with per-entry batch discard - StorageApi converts Response.violations to StoreError::Conflict - 7 new mock storage tests: CAS revision matching, CreateIfAbsent, CAS-on-remove (matching, mismatching, nonexistent, batch partial conflict) - StoreCommand serialization/deserialization for CAS-on-remove roundtrip Mapping engine (openstack-keystone-core): - Add authenticate_by_mapping pipeline: ruleset resolution, claim evaluation, HMAC-SHA256 virtual user ID derivation, and CAS-protected shadow upsert - Add claim evaluation engine with first-match-wins rule evaluation, AllOf/AnyOf/AllOfStrict criteria, regex matching, and interpolation - Add identity binding resolution with domain resolution mode enforcement - Add HMAC-SHA256 deterministic user ID derivation (dashless hex, 32 chars) for stable token serialization across backends - Add get_ruleset_by_source composite index lookup for (domain_id, source) - Add AuthenticationContext::Mapping to auth context enum with correct scope handling; authenticate_by_mapping emits authorization: None, scope resolution happens at new_for_scope time by reading VirtualUser.authorizations - Add calculate_effective_roles early-return for mapping context to bypass role assignment lookup (virtual users have no role assignments) - Add service-layer CAS retry with exponential backoff (5 retries, 50-800ms) for delete_ruleset and delete_virtual_user - Add allowed_domains O(1) HashSet lookup in engine with 256 cardinality limit - Add AllowedDomainsTooLarge error variant replacing misleading DomainClaimRequired - 39 new unit tests: 8 HMAC, 13 claim engine, 3 authenticate_by_mapping, 6 scope resolution (domain/project/system match, mismatch, not found, empty), 2 allowed_domains cardinality, 2 CAS retry limits, 5 CAS-on-remove Mapping driver (openstack-keystone-mapping-driver-raft): - Add get_ruleset_by_source with composite index key format - Add source index maintenance on ruleset create/update/delete - delete_ruleset_impl and delete_virtual_user_impl capture revision from StoreDataEnvelope and pass to Mutation::remove() with CAS - Convert StoreError::Conflict to MappingProviderError::CasConflict in delete_ruleset and delete_virtual_user public methods - Remove dead cas_upsert_virtual_user_impl (service layer handles retry) Security improvements: - Wrap cluster_salt with secrecy::SecretString for redaction - Fix HMAC byte conversion bug (u64 -> u32+u16 for last 6 bytes) - CAS prevents TOCTOU races on shadow registry upsert and deletion - is_system immutable (cannot be added after creation via update) Types (openstack-keystone-core-types): - Add MappingAuthRequest, MappingContext auth types - Add NoMatchingRule, DisabledRuleset, CasConflict, HmacDerivationFailed, AllowedDomainsTooLarge errors - Add IdentitySource::to_string_key() for stable index key generation Documentation (ADR-0020): - Remove IdentitySource::Mtls, TlsCaResource, and mTLS use cases
|
🦢 Load Test Results Goose Attack ReportPlan Overview
Request Metrics
Response Time Metrics
Status Code Metrics
Transaction Metrics
Scenario Metrics
|
|
| Branch | mapping |
| Testbed | ubuntu-latest |
Click to view all benchmark results
| Benchmark | Latency | Benchmark Result nanoseconds (ns) (Result Δ%) | Upper Boundary nanoseconds (ns) (Limit %) |
|---|---|---|---|
| Command_Serde/apply/remove | 📈 view plot 🚷 view threshold | 86,223.00 ns(-41.33%)Baseline: 146,967.05 ns | 485,192.41 ns (17.77%) |
| Command_Serde/apply/set | 📈 view plot 🚷 view threshold | 85,963.00 ns(-34.97%)Baseline: 132,180.70 ns | 300,096.53 ns (28.65%) |
| Command_Serde/pack/delete | 📈 view plot 🚷 view threshold | 123.67 ns(+1.62%)Baseline: 121.70 ns | 146.56 ns (84.38%) |
| Command_Serde/pack/delete_index | 📈 view plot 🚷 view threshold | 113.33 ns(-0.49%)Baseline: 113.89 ns | 137.31 ns (82.53%) |
| Command_Serde/pack/set | 📈 view plot 🚷 view threshold | 192.77 ns(-2.23%)Baseline: 197.18 ns | 241.24 ns (79.91%) |
| Command_Serde/pack/set_index | 📈 view plot 🚷 view threshold | 113.33 ns(-0.69%)Baseline: 114.12 ns | 137.25 ns (82.57%) |
| Command_Serde/unpack/delete | 📈 view plot 🚷 view threshold | 224.17 ns(+19.75%)Baseline: 187.20 ns | 229.91 ns (97.50%) |
| Command_Serde/unpack/delete_index | 📈 view plot 🚷 view threshold | 185.03 ns(+12.30%)Baseline: 164.77 ns | 205.96 ns (89.84%) |
| Command_Serde/unpack/set | 📈 view plot 🚷 view threshold | 265.28 ns(+8.36%)Baseline: 244.81 ns | 290.98 ns (91.17%) |
| Command_Serde/unpack/set_index | 📈 view plot 🚷 view threshold | 173.03 ns(+6.43%)Baseline: 162.57 ns | 203.06 ns (85.21%) |
| Payload_encryption/pack/inner | 📈 view plot 🚷 view threshold | 65.83 ns(+5.08%)Baseline: 62.64 ns | 78.33 ns (84.04%) |
| Payload_encryption/pack/remove_cmd | 📈 view plot 🚷 view threshold | 118.78 ns(-2.09%)Baseline: 121.31 ns | 156.19 ns (76.05%) |
| Payload_encryption/pack/set_cmd | 📈 view plot 🚷 view threshold | 217.06 ns(-4.54%)Baseline: 227.37 ns | 288.12 ns (75.34%) |
| Payload_encryption/unpack/inner | 📈 view plot 🚷 view threshold | 181.21 ns(+11.35%)Baseline: 162.74 ns | 191.08 ns (94.83%) |
| Payload_encryption/unpack/remove_cmd | 📈 view plot 🚷 view threshold | 226.54 ns(+15.17%)Baseline: 196.70 ns | 244.76 ns (92.56%) |
| Payload_encryption/unpack/set_cmd | 📈 view plot 🚷 view threshold | 281.23 ns(+9.52%)Baseline: 256.77 ns | 311.75 ns (90.21%) |
| Raft_1Node_Latency/prefix/1node | 📈 view plot 🚷 view threshold | 4,711,500.00 ns(+25.87%)Baseline: 3,743,032.24 ns | 6,991,269.19 ns (67.39%) |
| Raft_1Node_Latency/read/1node | 📈 view plot 🚷 view threshold | 650.54 ns(+15.29%)Baseline: 564.27 ns | 727.54 ns (89.42%) |
| Raft_1Node_Latency/remove/1node | 📈 view plot 🚷 view threshold | 241,660.00 ns(-36.86%)Baseline: 382,716.72 ns | 1,007,990.77 ns (23.97%) |
| Raft_1Node_Latency/write/1node | 📈 view plot 🚷 view threshold | 260,310.00 ns(-29.45%)Baseline: 368,966.55 ns | 798,607.11 ns (32.60%) |
| build_snapshot/default | 📈 view plot 🚷 view threshold | 95,812.00 ns(+3.34%)Baseline: 92,718.91 ns | 157,450.67 ns (60.85%) |
| fernet token/project | 📈 view plot 🚷 view threshold | 1,461.70 ns(+1.42%)Baseline: 1,441.21 ns | 1,664.73 ns (87.80%) |
| get_data_keyspace | 📈 view plot 🚷 view threshold | 0.35 ns(+9.70%)Baseline: 0.32 ns | 0.38 ns (92.41%) |
| get_db | 📈 view plot 🚷 view threshold | 0.35 ns(+9.93%)Baseline: 0.32 ns | 0.38 ns (92.47%) |
| get_fernet_token_timestamp/project | 📈 view plot 🚷 view threshold | 134.96 ns(-8.21%)Baseline: 147.03 ns | 175.36 ns (76.96%) |
| get_keyspace | 📈 view plot 🚷 view threshold | 4.80 ns(-3.32%)Baseline: 4.97 ns | 9.86 ns (48.73%) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.