Feature #52
openFeature #33: Canofy Control Centre Backend Development
Feature #46: Canofy Control Centre Onboarding Process
# [CANOFY-106] Create IAM Policy, Role & Instance Profile
0%
Description
[CANOFY-106] Create IAM Policy, Role & Instance Profile¶
Type: Story
Epic: New Client Onboarding — Automated AWS + Frappe Provisioning
Stage key: iam_setup (pipeline stage 6 of 15)
Component: utils/aws_client.py
User Story¶
As an operations engineer,
I want the client's EC2 instance to have exactly the IAM permissions it
needs (SSM management + its own S3 bucket) and nothing more,
so that the platform never stores AWS access keys anywhere, and a
compromised instance can't reach other clients' resources.
Description¶
Create, in order:
- An IAM policy granting read/write access to the client's own S3 bucket
only (bucket ARN scoped, from stage 5). - An IAM role with that policy attached plus the AWS-managed
AmazonSSMManagedInstanceCorepolicy (required for SSM-based remote
command execution — this app never uses SSH). - An instance profile wrapping that role, attached to the EC2 instance
from stage 1.
This is the mechanism that makes the "no SSH keys, no AWS access keys
anywhere in Frappe" rule actually work end-to-end — the instance
authenticates to AWS via its own attached role, not credentials we manage.
Configuration / Prerequisites¶
- Depends on stage 1 (
instance_id) and stage 5 (s3_bucket_name). - AWS account must permit IAM role/policy creation (an org-level SCP
restriction here would block this whole stage).
Acceptance Criteria¶
-
Policy grants access to exactly the client's own bucket — verify no
wildcardResource: "*"on S3 actions. -
Role includes
AmazonSSMManagedInstanceCore. - Instance profile is attached to the correct instance.
-
From the instance itself (once bootstrapped),
aws s3 ls s3://<other-client-bucket>fails with access denied, while the
instance's own bucket is accessible. -
Re-running this stage against already-created IAM resources (retry
scenario) does not fail on "already exists."
Test Cases¶
| ID | Scenario | Steps | Expected Result |
|---|---|---|---|
| TC-1 | Happy path | Run stage after bucket + instance exist | Policy, role, instance profile all created and correctly linked |
| TC-2 | Scoped access | From the instance, attempt S3 access to a different client's bucket | Denied |
| TC-3 | Own bucket access | From the instance, read/write to its own bucket | Succeeds |
| TC-4 | SSM works | From Control Centre, run any SSM command against this instance | Succeeds — confirms AmazonSSMManagedInstanceCore is correctly attached |
| TC-5 | Idempotent re-run | Re-run stage when IAM resources already exist from a prior attempt | Stage succeeds, does not attempt duplicate creation |
| TC-6 | SCP-blocked account | Run in an AWS account with an SCP denying iam:CreateRole
|
Stage fails with a clear permissions error, not a silent partial creation |
No data to display