mirror of
https://github.com/mulgadc/spinifex.git
synced 2026-10-15 09:01:31 +00:00
feat: iam groups doc
This commit is contained in:
@@ -0,0 +1,222 @@
|
||||
---
|
||||
title: "IAM Groups"
|
||||
description: "Organise IAM users into groups and manage permissions once for the whole team."
|
||||
category: "Identity"
|
||||
tags:
|
||||
- iam
|
||||
- groups
|
||||
- users
|
||||
- policies
|
||||
- security
|
||||
resources:
|
||||
- title: "Spinifex Repository"
|
||||
url: "https://github.com/mulgadc/spinifex"
|
||||
- title: "AWS IAM Groups Documentation"
|
||||
url: "https://docs.aws.amazon.com/IAM/latest/UserGuide/id_groups.html"
|
||||
---
|
||||
|
||||
# IAM Groups
|
||||
|
||||
> Organise IAM users into groups and manage permissions once for the whole team.
|
||||
|
||||
## Table of Contents
|
||||
|
||||
- [Overview](#overview)
|
||||
- [Prerequisites](#prerequisites)
|
||||
- [Groups](#groups)
|
||||
- [Membership](#membership)
|
||||
- [Group Policies](#group-policies)
|
||||
- [Putting It All Together](#putting-it-all-together)
|
||||
- [Troubleshooting](#troubleshooting)
|
||||
|
||||
---
|
||||
|
||||
## Overview
|
||||
|
||||
A group is a collection of IAM users. Policies attached to a group apply to every member, so instead of attaching the same policy to each developer individually, you attach it once to a `developers` group and manage membership.
|
||||
|
||||
Members inherit both the group's **attached managed policies** and its **inline policies**, combined with any policies on the user itself. Policy evaluation is the same as everywhere else: an explicit `Deny` in any applicable policy wins, and anything not allowed is denied.
|
||||
|
||||
Groups cannot be nested, and a group is not a principal — it cannot sign requests or own access keys. Like all IAM resources, groups are scoped to the account that creates them.
|
||||
|
||||
## Prerequisites
|
||||
|
||||
- A running Spinifex cluster with the AWS gateway started
|
||||
- AWS CLI configured with your account's profile. The default `spinifex` account created at cluster setup works out of the box; to work in a separate account, create one with `spx admin account create` (see [Spinifex Admin CLI](/docs/spinifex-admin-cli)):
|
||||
|
||||
```bash
|
||||
export AWS_PROFILE=spinifex
|
||||
```
|
||||
|
||||
## Instructions
|
||||
|
||||
## Groups
|
||||
|
||||
### Create a Group
|
||||
|
||||
```bash
|
||||
aws iam create-group --group-name developers
|
||||
```
|
||||
|
||||
```json
|
||||
{
|
||||
"Group": {
|
||||
"Path": "/",
|
||||
"GroupName": "developers",
|
||||
"GroupId": "AGPA1A2B3C4D5E6F7890",
|
||||
"Arn": "arn:aws:iam::000000000001:group/developers",
|
||||
"CreateDate": "2026-07-03T10:00:00Z"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Use `--path` to organise groups hierarchically:
|
||||
|
||||
```bash
|
||||
aws iam create-group --group-name ops --path /teams/
|
||||
```
|
||||
|
||||
### Get and List Groups
|
||||
|
||||
`get-group` returns the group and its members:
|
||||
|
||||
```bash
|
||||
aws iam get-group --group-name developers
|
||||
aws iam list-groups
|
||||
aws iam list-groups --path-prefix /teams/
|
||||
```
|
||||
|
||||
### Delete a Group
|
||||
|
||||
A group must have no members and no policies before it can be deleted — see [Cleaning up a group](#deleteconflict-when-deleting-a-group).
|
||||
|
||||
```bash
|
||||
aws iam delete-group --group-name developers
|
||||
```
|
||||
|
||||
## Membership
|
||||
|
||||
Add and remove users:
|
||||
|
||||
```bash
|
||||
aws iam add-user-to-group --group-name developers --user-name carol
|
||||
aws iam remove-user-from-group --group-name developers --user-name carol
|
||||
```
|
||||
|
||||
List a group's members (the `Users` array of `get-group`):
|
||||
|
||||
```bash
|
||||
aws iam get-group --group-name developers --query 'Users[].UserName'
|
||||
```
|
||||
|
||||
List the groups a user belongs to:
|
||||
|
||||
```bash
|
||||
aws iam list-groups-for-user --user-name carol --query 'Groups[].GroupName'
|
||||
```
|
||||
|
||||
> **Group membership blocks user deletion.** `delete-user` returns `DeleteConflict` while the user is still in any group — remove them from all groups first.
|
||||
|
||||
## Group Policies
|
||||
|
||||
### Attach a Managed Policy
|
||||
|
||||
```bash
|
||||
aws iam attach-group-policy --group-name developers \
|
||||
--policy-arn arn:aws:iam::000000000001:policy/EC2ReadOnly
|
||||
|
||||
aws iam list-attached-group-policies --group-name developers
|
||||
|
||||
aws iam detach-group-policy --group-name developers \
|
||||
--policy-arn arn:aws:iam::000000000001:policy/EC2ReadOnly
|
||||
```
|
||||
|
||||
See [IAM Users and Policies](/docs/iam-users-and-policies) for creating managed policies and the policy document format.
|
||||
|
||||
### Inline Group Policies
|
||||
|
||||
Inline policies live inside the group and are deleted with it:
|
||||
|
||||
```bash
|
||||
aws iam put-group-policy --group-name developers \
|
||||
--policy-name keypair-mgmt \
|
||||
--policy-document '{"Version":"2012-10-17","Statement":[{"Effect":"Allow","Action":["ec2:CreateKeyPair","ec2:DeleteKeyPair"],"Resource":"*"}]}'
|
||||
|
||||
aws iam list-group-policies --group-name developers
|
||||
aws iam get-group-policy --group-name developers --policy-name keypair-mgmt
|
||||
aws iam delete-group-policy --group-name developers --policy-name keypair-mgmt
|
||||
```
|
||||
|
||||
Members are authorised by the union of the group's attached and inline policies. A user in `developers` with the policies above can call `ec2:DescribeInstances` (via the attached `EC2ReadOnly`) and `ec2:CreateKeyPair` (via the inline policy), while anything not granted — say `ec2:RunInstances` — is denied.
|
||||
|
||||
## Putting It All Together
|
||||
|
||||
Onboard a team with shared permissions:
|
||||
|
||||
```bash
|
||||
# 1. Create the group and grant it permissions
|
||||
aws iam create-group --group-name developers
|
||||
aws iam attach-group-policy --group-name developers \
|
||||
--policy-arn arn:aws:iam::000000000001:policy/EC2ReadOnly
|
||||
|
||||
# 2. Create users and add them to the group
|
||||
aws iam create-user --user-name carol
|
||||
aws iam add-user-to-group --group-name developers --user-name carol
|
||||
|
||||
# 3. Create access keys and configure profiles as usual
|
||||
aws iam create-access-key --user-name carol
|
||||
|
||||
# 4. Verify: carol can describe instances via group policy, nothing more
|
||||
AWS_PROFILE=spinifex-carol aws ec2 describe-instances
|
||||
AWS_PROFILE=spinifex-carol aws ec2 run-instances --image-id ami-123 --instance-type t3.micro
|
||||
# ^ AccessDenied — not granted by the group
|
||||
```
|
||||
|
||||
To change the whole team's permissions later, edit the group's policies once — no per-user changes needed.
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### DeleteConflict When Deleting a Group
|
||||
|
||||
The group still has members, attached policies, or inline policies. Empty it first:
|
||||
|
||||
```bash
|
||||
# Members
|
||||
aws iam get-group --group-name developers --query 'Users[].UserName'
|
||||
aws iam remove-user-from-group --group-name developers --user-name carol
|
||||
|
||||
# Attached policies
|
||||
aws iam list-attached-group-policies --group-name developers
|
||||
aws iam detach-group-policy --group-name developers --policy-arn arn:aws:iam::000000000001:policy/EC2ReadOnly
|
||||
|
||||
# Inline policies
|
||||
aws iam list-group-policies --group-name developers
|
||||
aws iam delete-group-policy --group-name developers --policy-name keypair-mgmt
|
||||
|
||||
aws iam delete-group --group-name developers
|
||||
```
|
||||
|
||||
### DeleteConflict When Deleting a User
|
||||
|
||||
Group membership counts as a subordinate entity, alongside access keys and attached policies. Find and leave the user's groups:
|
||||
|
||||
```bash
|
||||
aws iam list-groups-for-user --user-name carol
|
||||
aws iam remove-user-from-group --group-name developers --user-name carol
|
||||
```
|
||||
|
||||
### NoSuchEntity
|
||||
|
||||
The group or user referenced does not exist — both `get-group` on a missing group and `add-user-to-group` with a missing user return this. Check spelling with `list-groups` / `list-users`.
|
||||
|
||||
### Member Still Denied After Attaching a Group Policy
|
||||
|
||||
Check the policy landed on the right group and the user is actually a member:
|
||||
|
||||
```bash
|
||||
aws iam list-groups-for-user --user-name carol
|
||||
aws iam list-attached-group-policies --group-name developers
|
||||
aws iam list-group-policies --group-name developers
|
||||
```
|
||||
|
||||
Remember an explicit `Deny` in any policy that applies to the user — their own or any of their groups' — overrides the `Allow`.
|
||||
@@ -33,7 +33,6 @@ resources:
|
||||
- [Managing Profile Associations at Runtime](#managing-profile-associations-at-runtime)
|
||||
- [Assuming a Role](#assuming-a-role)
|
||||
- [Cleaning Up](#cleaning-up)
|
||||
- [Command Reference](#command-reference)
|
||||
- [Troubleshooting](#troubleshooting)
|
||||
|
||||
---
|
||||
@@ -51,11 +50,10 @@ Like all IAM resources, roles and instance profiles are scoped to the account th
|
||||
## Prerequisites
|
||||
|
||||
- A running Spinifex cluster with the AWS gateway started
|
||||
- An account created via `spx admin account create` (see [Spinifex Admin CLI](/docs/spinifex-admin-cli))
|
||||
- AWS CLI configured with the account's profile:
|
||||
- AWS CLI configured with your account's profile. The default `spinifex` account created at cluster setup works out of the box; to work in a separate account, create one with `spx admin account create` (see [Spinifex Admin CLI](/docs/spinifex-admin-cli)):
|
||||
|
||||
```bash
|
||||
export AWS_PROFILE=spinifex-myteam
|
||||
export AWS_PROFILE=spinifex
|
||||
```
|
||||
|
||||
## Instructions
|
||||
@@ -327,34 +325,6 @@ aws iam detach-role-policy --role-name app-server \
|
||||
aws iam delete-role --role-name app-server
|
||||
```
|
||||
|
||||
## Command Reference
|
||||
|
||||
| Command | Key Parameters | Notes |
|
||||
| ------------------------------------------- | ----------------------------------------------------------------------------- | ------------------------------------ |
|
||||
| `create-role` | `--role-name`, `--assume-role-policy-document`, `--path`, `--description`, `--max-session-duration`, `--tags` | Trust policy required |
|
||||
| `get-role` | `--role-name` | |
|
||||
| `list-roles` | `--path-prefix` | |
|
||||
| `update-role` | `--role-name`, `--description`, `--max-session-duration` | |
|
||||
| `update-assume-role-policy` | `--role-name`, `--policy-document` | Replaces the trust policy |
|
||||
| `delete-role` | `--role-name` | Must have no policies or profiles |
|
||||
| `attach-role-policy` / `detach-role-policy` | `--role-name`, `--policy-arn` | |
|
||||
| `list-attached-role-policies` | `--role-name` | |
|
||||
| `put-role-policy` | `--role-name`, `--policy-name`, `--policy-document` | Inline policy |
|
||||
| `get-role-policy` / `delete-role-policy` | `--role-name`, `--policy-name` | |
|
||||
| `list-role-policies` | `--role-name` | Inline policy names |
|
||||
| `tag-role` / `untag-role` / `list-role-tags` | `--role-name`, `--tags`/`--tag-keys` | |
|
||||
| `create-instance-profile` | `--instance-profile-name`, `--path`, `--tags` | |
|
||||
| `get-instance-profile` | `--instance-profile-name` | Includes bound role |
|
||||
| `list-instance-profiles` | `--path-prefix` | |
|
||||
| `list-instance-profiles-for-role` | `--role-name` | |
|
||||
| `add-role-to-instance-profile` | `--instance-profile-name`, `--role-name` | Max 1 role per profile |
|
||||
| `remove-role-from-instance-profile` | `--instance-profile-name`, `--role-name` | |
|
||||
| `delete-instance-profile` | `--instance-profile-name` | Must contain no role |
|
||||
| `associate-iam-instance-profile` | `--instance-id`, `--iam-instance-profile` | Works on running instances |
|
||||
| `disassociate-iam-instance-profile` | `--association-id` | |
|
||||
| `replace-iam-instance-profile-association` | `--association-id`, `--iam-instance-profile` | Returns a new association ID |
|
||||
| `describe-iam-instance-profile-associations`| `--association-ids`, `--filters` (instance-id, state) | |
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### MalformedPolicyDocument When Creating a Role
|
||||
|
||||
@@ -30,14 +30,13 @@ resources:
|
||||
- [Policies](#policies)
|
||||
- [Attaching Policies](#attaching-policies)
|
||||
- [Putting It All Together](#putting-it-all-together)
|
||||
- [Command Reference](#command-reference)
|
||||
- [Troubleshooting](#troubleshooting)
|
||||
|
||||
---
|
||||
|
||||
## Overview
|
||||
|
||||
Spinifex implements AWS-compatible IAM covering user management, access key lifecycle, policy CRUD, and policy attachment. Inline user policies (`put-user-policy`), user and policy tagging, and IAM roles for EC2 instances (see [IMDS](/docs/imds)) are also supported. All IAM resources are scoped to the account that creates them — users in one account cannot see or modify resources in another.
|
||||
Spinifex implements AWS-compatible IAM covering user management, access key lifecycle, policy CRUD, and policy attachment. Inline user policies (`put-user-policy`), user and policy tagging, [groups](/docs/iam-groups), and [roles and instance profiles](/docs/iam-roles-and-instance-profiles) are also supported. All IAM resources are scoped to the account that creates them — users in one account cannot see or modify resources in another.
|
||||
|
||||
When you create an account with `spx admin account create`, Spinifex bootstraps a root user with an `AdministratorAccess` policy and writes the credentials to `~/.aws/credentials`. From there, you use the standard AWS CLI to manage additional users and permissions.
|
||||
|
||||
@@ -46,11 +45,10 @@ When you create an account with `spx admin account create`, Spinifex bootstraps
|
||||
## Prerequisites
|
||||
|
||||
- A running Spinifex cluster with the AWS gateway started
|
||||
- An account created via `spx admin account create` (see [Spinifex Admin CLI](/docs/spinifex-admin-cli))
|
||||
- AWS CLI configured with the account's profile:
|
||||
- AWS CLI configured with your account's profile. The default `spinifex` account created at cluster setup works out of the box; to work in a separate account, create one with `spx admin account create` (see [Spinifex Admin CLI](/docs/spinifex-admin-cli)):
|
||||
|
||||
```bash
|
||||
export AWS_PROFILE=spinifex-myteam
|
||||
export AWS_PROFILE=spinifex
|
||||
```
|
||||
|
||||
## Instructions
|
||||
@@ -459,36 +457,14 @@ AWS_PROFILE=spinifex-carol aws ec2 terminate-instances --instance-ids i-123
|
||||
# ^ This will be denied by the NoTerminate statement
|
||||
```
|
||||
|
||||
## Command Reference
|
||||
|
||||
| Command | Key Parameters | Notes |
|
||||
| ----------------------------- | -------------------------------------------- | --------------------------------- |
|
||||
| `create-user` | `--user-name`, `--path` | Path default: `/` |
|
||||
| `get-user` | `--user-name` | |
|
||||
| `list-users` | `--path-prefix` | |
|
||||
| `delete-user` | `--user-name` | Must have no keys or policies |
|
||||
| `create-access-key` | `--user-name` | Max 2 per user; secret shown once |
|
||||
| `list-access-keys` | `--user-name` | |
|
||||
| `delete-access-key` | `--user-name`, `--access-key-id` | |
|
||||
| `update-access-key` | `--user-name`, `--access-key-id`, `--status` | `Active` or `Inactive` |
|
||||
| `create-policy` | `--policy-name`, `--policy-document` | Max 6144 bytes |
|
||||
| `get-policy` | `--policy-arn` | Metadata only |
|
||||
| `get-policy-version` | `--policy-arn`, `--version-id` | Use `v1`; includes document |
|
||||
| `list-policy-versions` | `--policy-arn` | |
|
||||
| `list-policies` | | |
|
||||
| `delete-policy` | `--policy-arn` | Must not be attached |
|
||||
| `attach-user-policy` | `--user-name`, `--policy-arn` | Idempotent |
|
||||
| `detach-user-policy` | `--user-name`, `--policy-arn` | |
|
||||
| `list-attached-user-policies` | `--user-name` | |
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### AccessDenied on IAM Commands
|
||||
|
||||
The calling user must have IAM permissions. Attach a policy with `iam:*` actions, or use the root account profile:
|
||||
The calling user must have IAM permissions. Attach a policy with `iam:*` actions, or use the account's admin profile:
|
||||
|
||||
```bash
|
||||
export AWS_PROFILE=spinifex-myteam
|
||||
export AWS_PROFILE=spinifex
|
||||
aws iam list-users
|
||||
```
|
||||
|
||||
@@ -511,7 +487,7 @@ If the key was deleted, create a new one.
|
||||
|
||||
### DeleteConflict When Deleting a User
|
||||
|
||||
The user still has access keys or attached policies. Remove them first:
|
||||
The user still has access keys, attached policies, or [group memberships](/docs/iam-groups). Remove them first:
|
||||
|
||||
```bash
|
||||
# Check for access keys
|
||||
@@ -519,6 +495,9 @@ aws iam list-access-keys --user-name alice
|
||||
|
||||
# Check for attached policies
|
||||
aws iam list-attached-user-policies --user-name alice
|
||||
|
||||
# Check for group memberships
|
||||
aws iam list-groups-for-user --user-name alice
|
||||
```
|
||||
|
||||
### DeleteConflict When Deleting a Policy
|
||||
|
||||
Reference in New Issue
Block a user