Skip to content

Account Access and Scopes

What RosettaHub can do on each of your cloud accounts, how you decide it, and how to verify it for yourself.

The Trust Model

RosettaHub never holds your root or administrator credentials. You deploy a CloudFormation template that creates an IAM role in your account, and RosettaHub assumes that role to do its work. This is the same pattern used by cloud security and observability vendors generally, and it is what enterprise security reviews expect.

There are two hops, not one:

graph LR
    RH["RosettaHub"] -->|"AssumeRole + ExternalId"| CR["RosettaHubControlRole\n(your payer account)"]
    CR -->|"AssumeRole"| AR["RosettaHubAccessRole\n(each account)"]

    style RH fill:#e3f2fd,stroke:#1565c0,color:#000
    style CR fill:#fff9c4,stroke:#f9a825,color:#000
    style AR fill:#e8f5e9,stroke:#2e7d32,color:#000
  • RosettaHubControlRole lives in your management account. It carries ReadOnlyAccess plus the ability to assume the RosettaHub roles and to provision IAM resources named RosettaHub*. It is not an administrator.
  • RosettaHubAccessRole exists on each connected account and holds the capabilities you granted that account.

The outer hop, from RosettaHub into the control role, is protected by an sts:ExternalId unique to your organization. The inner hop is between two accounts you already own.

Access Scopes

What RosettaHub may do on an account is recorded as an independent set of scopes, not a level. Two accounts in the same organization can carry completely different sets.

Scope What it lets RosettaHub do How it is granted Administrative reach
READ_ONLY Describe resources across compute, storage, network, and identity Always No
FINOPS Collect billing and cost data Always No
MONITORING Run the real-time Monitoring Service Always No
PERMISSIONS Manage service control policies, organizational units, quota increases, alternate contacts EnablePermissions No
FEDERATION Sign your users directly into the cloud provider's console, and share resources across accounts EnableFederation Yes
METACLOUD Provision infrastructure on the account from Formations EnableMetacloud Yes
DESTROY Stop and delete resources: cleanup, account recycling, halting spend EnableDestroy Yes
LIFECYCLE Create accounts, use organization root access, change a member account's root email EnableLifecycle Only over accounts RosettaHub creates

The first three are the baseline every connected account receives. The rest are chosen per account.

The Three Roles

RosettaHub works through three roles on your accounts, each with a separate job. Which of them exist depends on what you granted.

Role What RosettaHub does through it Requires On member accounts On the management account
RosettaHubAccessRole Automates governance: manages permissions, sets up monitoring, collects cost data Always Resource-scoped policies. AdministratorAccess only under DESTROY Same
RosettaHubFederationRole Signs your users into the cloud console FEDERATION AdministratorAccess ReadOnlyAccess, with a read-only permissions boundary
RosettaHubKeysRole Provisions the infrastructure your Formations describe METACLOUD AdministratorAccess AdministratorAccess with the RosettaHubPolicy permissions boundary

Federation and MetaCloud widen what RosettaHub can do

They do it through a different role rather than by widening RosettaHubAccessRole, but the effect on the account is the same: granting either gives RosettaHub an administrative path on that account.

This is inherent to what they do. Federated console access means putting your user into the account with real permissions. Provisioning a Formation means creating whatever that Formation describes. Neither can be done from a read-only position.

If you need an account where RosettaHub has no administrative path at all, that is the Governance family with EnablePermissions -- and Federation, MetaCloud, and Destroy are not offered there, so none of them can be turned on by accident.

Why DESTROY is the one that attaches administrator rights

AdministratorAccess is attached to RosettaHubAccessRole under DESTROY, and only DESTROY.

Not to make deletion convenient. It is what lets RosettaOps stop an account spending: halting machines, cleaning up resources, and recycling the account when it is returned. An enforcement action that cannot actually stop the meter is not enforcement, and stopping arbitrary resources is an administrative act.

This is why DESTROY is commonly granted on development and sandbox accounts, where waste accumulates, and withheld on production.

LIFECYCLE is different: no attached administrator policy

LIFECYCLE does not attach AdministratorAccess to anything. Its own action set is small and fully enumerated. What it carries instead is structural, and it applies only to accounts RosettaHub creates for you:

Where it comes from
Administrative access to new accounts When AWS creates an account it plants OrganizationAccountAccessRole inside it, trusting the payer. RosettaHub uses that role to bootstrap RosettaHubAccessRole on the new account
Root recovery on new accounts The account's root email address is a RosettaHub-generated address, and the root email is the root credential

If you supply your own account IDs, neither applies. Bringing existing accounts means AWS never plants that role on our behalf and the root addresses stay yours. LIFECYCLE is only worth granting if you want RosettaHub creating accounts for you.

You can close the bootstrap path afterwards

The OrganizationAccountAccessRole route exists because a brand-new account has nothing else to bootstrap through. Once setup on an account is verified, it is no longer needed.

Deploying RosettaOpsOrgAccessRoleTrust narrows that role's trust to your own administrators, so RosettaHub can no longer assume it. We cannot undo that: nothing RosettaHub is granted includes permission to rewrite that role's trust policy. See Deployment Order for when to apply it.

What contains an administrative role

On a member account, the service control policy. It binds principals the account's own administrators cannot exempt, including its root user, which is why it is the containment layer rather than any policy attached to a single role.

RosettaHubFederationRole and RosettaHubKeysRole are both subject to it. That is what bounds the FEDERATION and METACLOUD grants: those roles are administrators of the account, and the service control policy is what they run inside.

Two roles are exempt, deliberately, and you should know which

The service control policies RosettaHub authors carry a standing exemption for two principals:

Exempt principal Why
OrganizationAccountAccessRole AWS's own role. Bootstrapping a new account runs as it, before any RosettaHub role exists to run as instead
RosettaHubAccessRole The role that writes and maintains these very policies. A policy engine that its own author cannot escape is a policy engine that can lock itself out of the account it governs

RosettaHubAccountReadOnlyAccessRole is exempt from the service-restriction statements for the same reason the audit reads have to keep working, and RosettaHubKeysRole carries narrow, statement-specific carve-outs where a blanket deny would stop it doing its job.

The consequence to be clear-eyed about. Under DESTROY, RosettaHubAccessRole holds AdministratorAccess and is exempt from the service control policies. On those accounts the SCP is not what bounds RosettaHub -- the grant is. That is the honest reading of DESTROY, and it is the reason to grant it on development and sandbox accounts rather than across the estate.

You can close the OrganizationAccountAccessRole half yourself once setup is verified, with RosettaOpsOrgAccessRoleTrust.

The management account is outside SCPs entirely

AWS does not apply service control policies to the management account at all. An administrator federation role there would therefore be unconstrained, which is a full-organization-takeover risk. The management account and the designated FinOps, audit, and log-archive accounts get a read-only federation role instead, with a read-only permissions boundary so it cannot be widened later.

The practical consequence: wherever you grant FEDERATION or METACLOUD on a member account, the organizational policy layer is doing the containing. It is not an optional extra.

Why LIFECYCLE is separate from PERMISSIONS

Everything above is the reason. None of it can be bounded by a policy on our side -- not even by a service control policy, in the case of the root email address. So rather than letting account creation travel silently with governance, it is gated behind its own grant that you can decline while still having a fully governed estate.

Scopes are recorded per account

Scopes are stored against each cloud account rather than against your contract or your edition. Granting DESTROY on your sandbox accounts does not grant it anywhere else, and changing a grant later does not require redeploying the rest of the estate.

The Two Template Families

The templates come in two families, and the difference is the one thing a security reviewer will look for.

Family Templates Parameters Contains AdministratorAccess Editions
Governance RosettaOpsGovernance, RosettaOpsGovernanceFunctional, RosettaOpsGovernanceManagement EnablePermissions No Observe, Govern
Admin RosettaOpsAdmin, RosettaOpsAdminFunctional, RosettaOpsAdminManagement EnableFederation, EnableMetacloud, EnableDestroy, EnableLifecycle Yes Automate

The Governance family covers two editions through one parameter:

Edition Deploys as
Observe RosettaOpsGovernance with EnablePermissions=false
Govern RosettaOpsGovernance with EnablePermissions=true

Moving from Observe to Govern is a parameter change on the same template. Moving to Automate means deploying the other family, deliberately -- which is the point, since that is where an administrative path first appears.

A family does not set the administrator switch to false. It does not have the switch.

The Governance templates declare no parameter that grants FEDERATION, METACLOUD, DESTROY or LIFECYCLE, so no combination of parameter values produces an administrative path. Converting an account means deploying the other family to it, deliberately.

The templates are published as plain CloudFormation and need no credentials to fetch, so read them rather than taking this on trust. The access scopes above name what each grant allows, and the roles name every principal created and what it holds -- which is a more useful review than searching for a policy name, since privilege can be reached by more routes than one.

With EnablePermissions=false, the Governance template is the Observe deployment: the same resources, with the governance statements omitted.

Observe is not read-only, and we do not describe it as such

Monitoring an account means deploying instrumentation into it. Even at Observe, the baseline creates EventBridge rules on cost-incurring events, CloudWatch alarms, an AWS Config recorder, a topic and queue for compliance findings, an OAM link to the audit account, and the IAM roles those run as -- every role created under a permissions boundary the same template provisions.

What Observe does not do is modify, stop, or delete a resource you run. That is the honest claim, and unlike "read-only" it survives someone opening the template.

Three variants per family

Each family has three variants, according to what the account is rather than what it may do:

Variant Deploy to
(base name) Ordinary member accounts, usually via StackSets
...Functional The accounts holding FinOps, audit, or the log archive
...Management The management (payer) account. Only this one registers the organization

Three further parameters -- FinopsAccountId, AuditAccountId, LogArchiveAccountId -- name which account plays each role. Each takes self, an account number, or empty.

Two more templates

Template Deployed by Purpose
RosettaOpsControlRole You, first, on the payer Creates RosettaHubControlRole. Every other template trusts it by ARN, and AWS validates a trust principal at creation time, so nothing else can deploy before it exists
RosettaOpsOrgAccessRoleTrust You, last, per account Narrows the trust on AWS's own OrganizationAccountAccessRole so RosettaHub can no longer assume it

Neither is part of the family grid: the control role is prerequisite plumbing, and the trust template takes access away from RosettaHub rather than granting it.

Deployment Order

The order is not arbitrary. Each phase depends on something the previous one created.

graph TD
    P1["1. RosettaOpsControlRole\non the payer"] --> P2["2. Functional accounts\nFinOps, audit, log archive"]
    P2 --> P3["3. Management template\non the payer"]
    P3 --> P4["4. Member accounts\nvia StackSet"]

    style P1 fill:#e3f2fd,stroke:#1565c0,color:#000
    style P2 fill:#e3f2fd,stroke:#1565c0,color:#000
    style P3 fill:#fff9c4,stroke:#f9a825,color:#000
    style P4 fill:#e8f5e9,stroke:#2e7d32,color:#000
  1. The control role, on the payer. Everything else names it in a trust policy, and AWS validates trust principals at creation time.
  2. The functional accounts. These carry no Lambda, which is what lets them run this early.
  3. The management template. Its registration records the organization and names the functional accounts, which by now actually hold their roles.
  4. The member accounts. Each registers itself against the organization created in step 3.

Deploy RosettaOpsOrgAccessRoleTrust last, and only where setup is verified

This template takes access away from RosettaHub rather than granting it, by narrowing the trust on OrganizationAccountAccessRole to your own administrators. Setup on a newly created account runs as that role, so applying it before RosettaHubAccessRole exists leaves the account unreachable by RosettaHub until it is recovered. Recovery is possible -- a StackSet can restore the role, and the same route covers a wrong principal list -- so ask us if you need it. Deleting the stack also restores the AWS default trust.

Apply it only to accounts whose setup has been verified. The stack refuses an empty principal list and restores the AWS default trust if you delete it.

What Gets Created on Your Account

Everything RosettaHub provisions is named RosettaHub*, so it is easy to find, audit, and remove. There are two groups, and the difference matters.

The role RosettaHub assumes

Resource Purpose
RosettaHubAccessRole The role RosettaHub assumes on this account
RosettaHubBasePolicy Read and describe permissions
RosettaHubMonitoringPolicy The real-time Monitoring Service
RosettaHubDiagnosticsPolicy Setup verification and diagnostics
RosettaHubFinopsPolicy Billing and cost data, on the FinOps account
RosettaHubLogArchivePolicy Central log storage, on the log archive account
RosettaHubScopePolicy The granted scopes, merged into one document

Under DESTROY this role holds AdministratorAccess instead of the granular set, and the granular policies are not attached. Otherwise it holds ReadOnlyAccess plus exactly the documents above.

The monitoring instrumentation

Present on every connected account, including at Observe, because this is what monitoring an account consists of.

Resource Purpose
EventBridge rules Fire on cost-incurring events, feeding the real-time cost engine
CloudWatch alarms Budget and threshold signals
AWS Config recorder Compliance posture scanning
SNS topic and SQS queue Delivery of compliance findings
OAM link Ships observability data to your audit account
RosettaHubEventBusRole and the audit read-only role The identities the above run as. Created only under a RosettaHubBoundary* permissions boundary that the same template provisions

None of these read or alter a resource you run. They are RosettaHub's own instrumentation, named RosettaHub*, and removing the stacks removes them.

Sessions are bounded even under an administrator grant

Where a grant carries administrator rights, individual operations still run under a session policy scoped to the task. A cleanup session is bounded by the teardown policy, monitoring by its own document set, and so on.

The roles behind console access and provisioning

These exist only where you granted the matching scope. RosettaHub assumes them to sign your users in and to build what your Formations describe.

Resource Requires What it holds
RosettaHubFederationRole FEDERATION AdministratorAccess on member accounts. ReadOnlyAccess with a read-only permissions boundary on the management, FinOps, audit, and log-archive accounts
RosettaHubKeysRole METACLOUD AdministratorAccess, with the RosettaHubPolicy permissions boundary applied on the management account

On member accounts these are constrained by the service control policy on the account rather than by their own policy. See The Three Roles before granting either scope.

Neither can appear under the Governance family

EnableFederation and EnableMetacloud are Admin-family parameters only. A Governance deployment cannot create either role, whatever its parameters are set to.

Customer-Owned Data

Your cost and billing data is stored in your cloud account, not in RosettaHub's. It lands in the FinOps account in the open FOCUS 1.3 format, and queries run through your cloud's own serverless query engine, so you pay only your cloud's query cost. There are no ingestion fees, no per-gigabyte charges, and no copy of your cost history in a vendor data lake.

What RosettaHub does hold

Being exact about this is worth more than a broader claim, because the broader claim does not survive a question.

RosettaHub keeps a rolling operational cache: a live inventory of your running resources and recent AI model usage, held for 48 hours and continuously replaced. It exists for one reason -- the live cost estimate is the last 48 hours of activity added to your most recent billing data, so the platform needs the recent half of that sum close at hand.

Where it lives Retention
Cost and billing history, FOCUS tables Your FinOps account Yours, indefinitely
Compliance findings, logs, trails Your audit and log-archive accounts Yours, indefinitely
Live resource inventory, recent AI usage RosettaHub 48 hours, rolling

Three things follow, and each is checkable:

  • It is a cache, not a record. Everything in it is reconstructible from your own CloudTrail. If it were deleted, the platform would rebuild it from your data.
  • It holds no history. There is no long-run picture of your estate in our systems. Ask what we would still have about you in a week and the answer is nothing beyond your account registration.
  • Your cost data is never in it. The FOCUS tables, the billing reports and the query engine are all in your FinOps account, and always were.

If a 48-hour cache is not acceptable

For sovereign, air-gapped, or strict-residency deployments this window can be moved into your own estate. It is not the default because it costs a cross-account query on every console view, which most customers would rather not pay for. Ask if your requirements need it.

Next Steps