Skip to content

feat(identity-center): complete IAM Identity Center emulation - #3331

Merged
pgermosen merged 99 commits into
floci-io:mainfrom
KenkoGeek:feature/identity-center-complete
Sep 10, 2026
Merged

feat(identity-center): complete IAM Identity Center emulation#3331
pgermosen merged 99 commits into
floci-io:mainfrom
KenkoGeek:feature/identity-center-complete

Conversation

@KenkoGeek

Copy link
Copy Markdown
Contributor

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:

  • SSO Admin: 79/79
  • IAM Identity Center OIDC: 4/4
  • IAM Identity Center Access Portal: 4/4
  • Identity Store: 19/19
  • SCIM: 15/15

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

  • Bug fix (fix:)
  • New feature (feat:)
  • Breaking change (feat!: or fix!:)
  • Docs / chore

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.0 request/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 GetCallerIdentity to 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 CreateTokenWithIAM following 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 --strict
  • python3 tools/docs/regen_cfn_resource_types.py --strict
  • make docs-check
  • git diff origin/main...HEAD --check

The branch was rebased cleanly onto the current upstream main before opening this PR.

Checklist

  • ./mvnw test passes locally
  • New or updated integration test added
  • Commit messages follow Conventional Commits

./mvnw test was 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.

@github-actions

Copy link
Copy Markdown

🎉 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:

  • Link the issue this fixes with Closes #N in the description
  • Commits follow Conventional Commits (feat(s3): ..., fix(dynamodb): ...)
  • Behaviour changes come with a test — see CONTRIBUTING.md

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.

@greptile-apps

greptile-apps Bot commented Sep 10, 2026

Copy link
Copy Markdown

Greptile Summary

The pull request completes IAM Identity Center emulation across SSO Admin, OIDC, Access Portal, Identity Store, and SCIM, including account-aware state, SDK compatibility coverage, and end-to-end credential flows. Changes since the prior review also add Marketplace Agreement support, regional MSK isolation, China-region KMS SM2 signing, and stricter TLS proxy startup behavior.

  • Adds broad Identity Center API, persistence, authentication, portal, and compatibility-test coverage.
  • Registers Marketplace Agreement JSON protocol routing and implements agreement lifecycle operations.
  • Adds SM2 KMS signing and verification for supported China regions.
  • Makes MSK cluster and runtime identities account- and region-aware.
  • Fails startup when the TLS proxy cannot bind its public listener.
  • One Marketplace Agreement state-machine issue remains: terminal requests can be transitioned again.

Confidence Score: 4/5

The PR is not yet safe to merge because Marketplace Agreement terminal payment and cancellation requests can be rewritten into conflicting states.

Payment and cancellation transition handlers do not validate their current state, allowing rejected or cancelled requests to be approved later and potentially cancelling an agreement through an invalid transition. All four previous Identity Center findings were manually resolved and are not outstanding in the current code.

Files Needing Attention: src/main/java/io/github/hectorvent/floci/services/marketplace/MarketplaceAgreementService.java

Important Files Changed

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
Loading

Reviews (11): Last reviewed commit: "fix(identity-center): register refresh t..." | Re-trigger Greptile

Comment thread src/main/java/io/github/hectorvent/floci/services/ssooidc/SsoOidcController.java Outdated
Comment thread src/main/java/io/github/hectorvent/floci/services/ssoadmin/SsoAdminService.java Outdated
@hectorvent hectorvent added enhancement New feature or request floci-core identitystore AWS identitystore ssoadmin AWS ssoadmin labels Sep 10, 2026

@pgermosen pgermosen left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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 pgermosen added the waiting-author Review posted; waiting on the PR author to respond label Sep 10, 2026

@pgermosen pgermosen left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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 pgermosen left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

@KenkoGeek
KenkoGeek force-pushed the feature/identity-center-complete branch from 94b1d15 to aa7eed0 Compare September 10, 2026 19:37

@pgermosen pgermosen left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

@pgermosen pgermosen removed the waiting-author Review posted; waiting on the PR author to respond label Sep 10, 2026
@pgermosen
pgermosen merged commit cbfa034 into floci-io:main Sep 10, 2026
24 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request floci-core identitystore AWS identitystore ssoadmin AWS ssoadmin

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants