Authentication and Permissions
How an admin session is established, and what the IAM role behind it can do. user_auth.md is the authority for the identity model as a whole; this page covers the admin half of it.
Identity providers
ESP RainMaker Neo uses two separate Cognito User Pools:
Population |
Provider |
Federated as |
Self-signup |
|---|---|---|---|
Admins |
Cognito user pool |
a Cognito provider on the pool’s |
Disabled — admins are provisioned |
End users |
the ESP User OIDC issuer |
an IAM OIDC identity provider, keyed on the issuer URL |
Enabled |
The ESP-End-Users Cognito pool exists, but end users do not present its tokens
to ESP RainMaker Neo: it sits behind the ESP User issuer, which is what the Identity Pool
trusts. An admin token and an end-user tofperefore differ in issuer, which is
how POST /v1/user/credentials tells them apart.
The admin pool declares two custom attributes: custom:super_admin (max 4
characters, so the value is the string "true") and custom:user_id.
From admin login to AWS credentials
The admin signs in against
ESP-Admin-Usersand receives Cognito tokens.POST /v1/user/credentialsexchanges them for Identity-Pool credentials. The route carries no gateway authorizer; the handler verifies the access token (header) andid_token(body) against the admin pool’s JWKS as a pair. See user_auth.md §3.1.Every other admin endpoint is
AWS_IAM, so the admin SigV4-signs it with those credentials. No bearer token is presented to the admin APIs.
Role selection
The Identity Pool has exactly one role mapping, on the admin pool’s client:
A token from the admin pool carrying
custom:super_admin == "true"maps toAdminDeviceUsersRole.Everything else — including every federated end user — falls through to the pool’s default
authenticatedrole,DeviceUsersRole. There is no role mapping on the OIDC provider and no per-audbranching.
So admin privilege is an infrastructure fact: which role the identity pool will hand you, decided before any ESP RainMaker Neo Lambda runs.
Super-admin resolution in the handlers
Being on AdminDeviceUsersRole gets a caller to the endpoint; the handler still
re-checks super-admin status, and where it reads that from depends on the
path:
SigV4 admin endpoints (the normal case). There is no token in the request, only the API Gateway identity. The handler resolves the caller and calls Cognito
AdminGetUser, reading thecustom:super_adminuser attribute. Its value is authoritative.Token-verifying endpoints (
/v1/user/credentialsand the ESP-User surface). Thecustom:super_adminclaim is read from the verified Cognito token. Cognito emits custom attributes in the ID token, not the access token.
Either way the handler answers 403 when the caller is not a super admin.
The user_details table declares an is_super_admin attribute, but no ESP RainMaker Neo code
path reads or writes it — only the test harness sets it. Do not treat it as a
source of truth.
AdminDeviceUsersRole
Trust: sts:AssumeRoleWithWebIdentity by cognito-identity.amazonaws.com,
conditioned on this identity pool’s id and an amr of authenticated. The role
trusts the pool, not the login provider.
AWS IoT Core (all on *)
Action |
What it enables |
|---|---|
|
Enumerate devices; per-device registry detail |
|
Query the fleet index (registry + |
|
Read group hierarchy and membership |
|
Manage groups, including editing a description |
|
Manage dynamic (query-backed) groups |
|
Assign / unassign a device |
|
OTA job lifecycle |
|
Per-job and per-device execution status |
|
IoT streams for OTA firmware delivery |
S3
Action |
Resource |
|---|---|
|
|
|
|
The bucket name is resolved per deployment and region, so it is not a fixed string. OTA firmware and the node-registration certificate CSVs are the two prefixes granted.
Other
Effect |
Action |
Resource |
Purpose |
|---|---|---|---|
Allow |
|
|
Refresh credentials |
Allow |
|
|
Call any ESP RainMaker Neo API endpoint, and nothing outside it |
Allow |
|
IoT user role |
Tag assumed sessions |
Allow |
|
OTA service role |
Required to create an OTA job |
Allow |
|
|
Detect which optional module stacks are deployed, so the dashboard surfaces a feature only when its stack exists. |
Deny |
|
|
Blocks credential escalation into any other role |
The sts:AssumeRole deny is explicit, so it wins over any allow — an admin
cannot widen its own scope by assuming a broader role.
Not granted
Missing action |
Consequence |
|---|---|
|
Shadows are not readable through the REST API; the dashboard sees only what the fleet index projects |
|
Shadows are read-only from the dashboard. IoT Data Plane also requires an IoT policy attached to the Cognito identity, so adding the IAM action alone would not be enough |
|
Shadows cannot be deleted |
|
Shadow names cannot be enumerated |
|
The fleet-indexing configuration is not inspectable |
Any |
No direct table access — every read and write goes through a Lambda API, which is where RBAC is enforced |
OTA service role
A separate role, assumed by iot.amazonaws.com rather than by the admin.
AdminDeviceUsersRole holds iam:PassRole on it, which is what lets an admin
create an OTA job that AWS IoT then executes under this role:
s3:GetObject,s3:GetObjectVersionon<files-bucket>/ota/*iot:CreateJob,iot:DescribeJob,iot:DeleteJob,iot:GetOTAUpdateiot:CreateStream,iot:DescribeStream,iot:DeleteStreamiam:PassRoleon itself