# Section 3 — Identity, Authentication, and Permissions > Companion to [`musehub-production-readiness-checklist.md`](../musehub-production-readiness-checklist.md). ## Update (2026-09-07) — re-verified with full account access Every blocked check from the original pass is now runnable. Re-ran all of them. ### Root and Recovery Access - [x] **No root access keys** — `AccountAccessKeysPresent: 0` confirmed on both Nonproduction and Production via `aws iam get-account-summary`. - [x] **Root MFA** — enabled on Management and Production (Authenticator, unique passwords). Nonproduction correctly shows `AccountMFAEnabled: 0` because it has no standing root credential at all (centralized root access management) — not a gap, the intended end state. See the identity model doc for the full reasoning. - [ ] Documented legitimate root uses, multi-person root approval — still not formally written down anywhere as a policy, even though the mechanism (centralized root access management) that would enforce it now exists. ### Human Access - [x] IAM Identity Center (`MuseHub-Workforce`) confirmed live via `aws sso-admin list-instances` — `ACTIVE`, owned by the Management account, created 2026-08-21. - [x] Gabriel and Aaron have individual identities, MFA, and `AdministratorAccess` on all three accounts (superseding the original scoped `Operator` plan — Gabriel's deliberate decision, see #150/#152 history). - [ ] Sol/Toby/Ben's `StagingOperator` access — still intentionally deferred, no active need yet. ### Workload Access — full IAM inventory (previously impossible; `iam:ListUsers` was denied) **Nonproduction has 5 IAM users** (Production has 0, by design): | User | Policies | Key age | Key status | Notes | |---|---|---|---|---| | `musehub-infra` | `AmazonSSMFullAccess`, `AmazonEC2FullAccess`, `AmazonRDSFullAccess`, `AmazonS3FullAccess` + inline `musehub-ecr-push` | since 2026-04-05 | Active | No longer used by `push.sh` (see #150) — still exists as a live, usable credential. Broader than previously documented; not narrowly scoped as the original pass assumed. | | `musehub-app` | `AmazonRDSDataFullAccess`, `AmazonS3FullAccess` | since 2026-04-05 | Active | App-level DB+storage access, reasonably scoped to its role | | `stori-assets-app` | `AmazonEC2FullAccess`, `AmazonS3FullAccess` + inline `stori-assets-s3-read` | since 2026-01-30 | Active | `EC2FullAccess` is broader than an "assets app" name suggests — worth Stori-side confirmation of what it actually needs | | `stori-admin` | **`AdministratorAccess`** (full account) | since 2026-01-29 | Active | **Real risk** — full admin access to the entire shared Nonproduction account via a static, unrotated key, for an unrelated project. Flagged to Gabriel 2026-09-07; deliberately not touched, since it's Stori's credential and modifying/deleting it without checking with whoever manages Stori's access could break their operations. Tracked in follow-up. | | ~~`s3-migration-temp`~~ | ~~`AmazonS3FullAccess`~~ | — | — | **Deleted 2026-09-07** — access key was already inactive, clearly dead weight from a past migration. Removed entirely (key detached, policy detached, user deleted). | - [x] Every service has its own IAM user, confirmed — no shared workload credential across services (this was already true, now fully verified rather than inferred). - [ ] AWS keys in source code — still confirmed clean (no keys committed); moot for GitHub secrets since GitHub isn't used for CI here. - [ ] Deployment role restricted to correct repo/branch/account/resources — not applicable; no automated (CI-triggered) deployment role exists at all yet (see #173 roadmap item). - [x] **Separate staging/production deployment auth** — resolved as of #150: `push.sh` uses each operator's own SSO session per environment, not a single shared credential across both. - [ ] Temporary/STS credentials everywhere — still not done for the workload IAM users above; all four remaining users have long-lived static access keys, none rotated since creation. ## The actual work items here — updated 1. ~~Get the broader read-access grant~~ — done. 2. ~~Set up IAM Identity Center~~ — done. 3. ~~Replace the shared `musehub-infra` laptop credential for human deploys~~ — done (#150). 4. **New, from today's inventory**: decide what to do with `stori-admin`'s full admin access — needs a conversation with whoever manages Stori's AWS access, not something to resolve unilaterally from here. 5. **New, from today's inventory**: rotate or move to STS-issued temporary credentials for `musehub-infra`, `musehub-app`, and `stori-assets-app` — all have long-lived static keys, some over 7 months old with no rotation. 6. Retire `musehub-infra` fully once the other scripts that still reference it are updated (#175).