feat(identity-center): complete IAM Identity Center emulation - #3331
Conversation
|
🎉 Thanks for your first pull request to Floci! Your CI checks need a maintainer to approve them before they run. That is GitHub's standard gate on first-time contributors, not a problem with your PR — so if the checks look like they are doing nothing, that is why. Once a maintainer approves, CI and the compatibility suite start automatically. Nothing is needed from you in the meantime. While you wait, a couple of things that make review faster:
Come join us in Slack — it is the fastest way to reach maintainers if you get stuck, or want feedback on an approach before investing more time in it. |
|
| Filename | Overview |
|---|---|
| src/main/java/io/github/hectorvent/floci/services/ssoadmin/SsoAdminService.java | Implements the expanded SSO Admin resource and assignment surfaces with account-aware persistence. |
| src/main/java/io/github/hectorvent/floci/services/ssooidc/SsoOidcService.java | Implements OIDC client registration, authorization grants, token issuance, refresh, and session handling. |
| src/main/java/io/github/hectorvent/floci/services/ssoportal/SsoPortalService.java | Implements portal account and role discovery, temporary credentials, session validation, and logout behavior. |
| src/main/java/io/github/hectorvent/floci/services/identitystore/ScimController.java | Adds authenticated SCIM user and group management integrated with Identity Store. |
| src/main/java/io/github/hectorvent/floci/services/marketplace/MarketplaceAgreementService.java | Adds Marketplace Agreement lifecycle operations, but terminal payment and cancellation requests can be transitioned again. |
| src/main/java/io/github/hectorvent/floci/services/kms/KmsService.java | Adds region-restricted SM2 key generation, signing, verification, and persistence loading. |
| src/main/java/io/github/hectorvent/floci/services/msk/MskService.java | Scopes MSK clusters and resource visibility to the request region while retaining legacy records. |
| src/main/java/io/github/hectorvent/floci/config/TlsProxyServer.java | Makes public TLS proxy bind failure abort startup synchronously. |
Sequence Diagram
sequenceDiagram
participant Client as AWS SDK Client
participant Routing as Protocol and Account Routing
participant Service as Identity Center / Marketplace Service
participant Storage as Account-aware Storage
participant Runtime as STS / KMS / MSK Runtime
Client->>Routing: AWS-shaped request
Routing->>Routing: Resolve protocol, account, and region
Routing->>Service: Dispatch modeled operation
Service->>Storage: Read or update scoped state
Storage-->>Service: Scoped resource state
opt Runtime-backed operation
Service->>Runtime: Issue credentials or manage runtime resource
Runtime-->>Service: Runtime result
end
Service-->>Routing: AWS-shaped response or modeled error
Routing-->>Client: SDK-compatible response
Reviews (11): Last reviewed commit: "fix(identity-center): register refresh t..." | Re-trigger Greptile
pgermosen
left a comment
There was a problem hiding this comment.
This is a huge and unusually well-researched PR, so first: real credit for how the SCIM and SSO OIDC implementations turned out. Filter grammar quirks, cursor-based pagination instead of startIndex, the empty-members-list behavior on groups, the PUT-returns-201 detail, the OAuth-shaped error envelope, RFC 8628 device flow with actual slow_down/authorization_pending/expired_token semantics, the trusted-token-issuer JWT handling honestly disclaiming JWKS verification rather than pretending to check it, all of that checked out against AWS's actual documented behavior, including several details that would be easy to get wrong.
The one blocker: the new SSO Portal controller shares SSO Admin's service descriptor, but a real AWS SDK client for that API (the one aws sso login and get-role-credentials use) signs requests with awsssoportal as the SigV4 service name, not sso. That signing name isn't registered anywhere in the catalog, and AwsProtocolClaimFilter rejects any REST request signed for a service it doesn't recognize (reject-unknown-service-scope is true in both the main and test application.yml, untouched by this PR). So a genuine SDK or CLI call to the Portal API would get rejected with a 404 before it ever reaches SsoPortalController, which runs against the compatibility coverage this PR claims for the SSO Portal client and the STS round-trip through issued Portal credentials. The fix should be small, registering awsssoportal alongside sso's existing credential scope, or giving Portal its own descriptor, but it's worth actually running SsoPortalTest against a live build afterward to confirm rather than trusting it from the diff.
A few other things worth picking up: the README's service table wasn't updated for OIDC, the Access Portal, or SCIM even though the docs pages, mkdocs nav, and service matrix all were. The new SSO Admin code builds ARNs with hardcoded arn:aws: string literals rather than the AwsArnUtils/AwsRegions helper that just landed, so it won't inherit partition-awareness if that gets extended later. SsoPortalService doesn't have a unit test the way the other new services do, only an integration test. And ScimController is 1461 lines handling routing, validation, and response shaping together, which is a lot for one class even for a first cut, splitting Users/Groups/Schema apart would help down the line.
None of that second group is blocking, just worth addressing alongside the Portal fix.
pgermosen
left a comment
There was a problem hiding this comment.
CI's native arm64 / sdk-test-java job is failing, four tests, all in your newest test code rather than the implementation. Good news on the Portal dispatch fix from the last round: it's working, all four failures happen downstream of it.
Two are stale test assertions rather than bugs. SsoAdminAccountAssignmentTest.createApplicationUsesAwsSdk correctly asserts the post-update name/status/origin on the described object, then a few lines later asserts the pre-update values again on the same object, looks like a leftover block from before the update-then-redescribe check was added. createTrustedTokenIssuerUsesAwsSdk has the same shape: it correctly confirms the rename to SdkIssuerUpdated, then a later listTrustedTokenIssuers assertion on the same ARN still expects the old SdkIssuer name.
The other two are a real gap in the test helper. SsoOidcTest's startDeviceAuthorizationUsesAwsSdk and SsoPortalTest's authorizeDevice both hit verificationUriComplete with a bare java.net.http.HttpClient.newHttpClient(), no trust configuration, and it fails with PKIX path building failed in this TLS-enabled job while every AWS SDK call in the same run succeeds. Since that code path only ever runs against the local emulator, giving that specific client a permissive SSLContext should fix it.
pgermosen
left a comment
There was a problem hiding this comment.
Good progress, three of the four failures are actually fixed now, confirmed the stale assertions and the SsoPortalTest TLS/endpoint fix both work.
SsoOidcTest.startDeviceAuthorizationUsesAwsSdk still fails though, different symptom now: the browser GET to the verification URL succeeds (200), but the immediate createToken call right after it comes back with a plain 400. Didn't find an obvious bug in resolveLocalPrincipal, a missing principal_id on the GET falls back to the configured local principal fine, so on paper the device should be authorized by the time createToken runs. Couldn't pin the exact rejection from the CI log though, whatever's failing there isn't logged at a level that got captured.
94b1d15 to
aa7eed0
Compare
pgermosen
left a comment
There was a problem hiding this comment.
Went back through everything from the last two rounds and it all checks out in the actual code, not just the commit messages. The Portal signing-name fix is confirmed working, the two stale test assertions now check the post-update values, and the TLS handshake failures are fixed with a properly scoped trust-all HttpClient that's only used by the emulator-only browser-flow tests. The application-provider ARN partition fix is solid too, I checked that a cn-north-1 instance genuinely gets an arn:aws-cn ARN now instead of a hardcoded arn:aws one, and there's a test proving it.
CI is fully green including the job that was failing before. What's left is cosmetic, ScimController is still one large file mixing routing and validation, which was already flagged as a reasonable first cut rather than something to hold this up over, plus one harmless redundant status code parameter. Nothing here should block merge.
This was a genuinely large, well-researched piece of work, especially the SCIM and device-flow implementations. Thanks for sticking with it through the review rounds.
Summary
Completes Floci's AWS IAM Identity Center emulation across the current public API surfaces, covering SSO Admin, IAM Identity Center OIDC, the IAM Identity Center Access Portal, Identity Store, and SCIM.
The implementation follows current AWS API documentation and AWS SDK for Java v2 wire contracts, preserves Floci's existing controller/service/storage patterns, adds account-aware persistence and reset behavior where required, and includes service, HTTP integration, and AWS SDK compatibility coverage for the new behavior.
Current operation coverage audited against the AWS references:
The work also adds end-to-end Identity Center flows including account assignments, permission-set based portal role discovery, temporary role credentials usable with Floci STS, OIDC device/auth-code/refresh flows, IAM-authenticated token flows, Portal logout semantics, and documentation/service matrix updates.
Type of change
fix:)feat:)feat!:orfix!:)AWS Compatibility
Verified against the current AWS IAM Identity Center API references for SSO Admin, OIDC, Access Portal, Identity Store, and the IAM Identity Center SCIM implementation guidance, together with AWS SDK for Java v2
2.52.0request/response models and marshallers.The implementation uses the documented AWS wire protocols, routes, request/response shapes, pagination contracts, validation rules, ARN and identifier forms, and modeled error semantics for the covered operations.
AWS SDK compatibility coverage includes the SSO Admin, SSO OIDC, and SSO Portal clients. Portal role credentials are also exercised through STS
GetCallerIdentityto confirm that issued temporary credentials route signed emulator calls to the assigned target account.Documented emulator-specific behavior is kept explicit where Floci cannot reproduce an external AWS dependency exactly. For example, local OIDC authorization endpoints and token lifetimes use emulator defaults, SigV4 presence is required for
CreateTokenWithIAMfollowing Floci's existing signing-validation approach, and trusted-token-issuer JWT handling validates modeled claims/configuration without external JWKS signature retrieval.Validation performed locally without running the heavyweight full Maven test suite:
python3 tools/docs/regen_action_docs.py --strictpython3 tools/docs/regen_cfn_resource_types.py --strictmake docs-checkgit diff origin/main...HEAD --checkThe branch was rebased cleanly onto the current upstream
mainbefore opening this PR.Checklist
./mvnw testpasses locally./mvnw testwas intentionally not run locally because the available machine is not suitable for Floci's heavyweight full Maven suite. The focused source, AWS SDK compatibility, documentation, generated-doc consistency, and diff checks were completed instead; CI is expected to run the upstream test matrix.