Administrator guide
Administrators manage Cloud Certainty Watchtower from Administration in the portal (PortalUrl):
roles, connections, grants, code integrations, repositories, ingest tokens, sync, settings, usage,
the audit log, and the licence. Everything is stored in the stack's DynamoDB table in your account
(integration tokens in AWS Secrets Manager), and every change is written to the audit log.
Administration has the tabs Roles, Connections, Grants, Integrations, Repositories, Ingest tokens, Sync, Settings, Usage, Audit log and Licence and about.
Roles
| Role | Can |
|---|---|
| User | Use the findings their grants allow: view, triage and fix, as granted. Own saved views, create tasks and exceptions within their grants |
| Administrator | Every permission on every finding of every connection (still bounded by each connection's access level and the plan), plus Administration. Administrators can change and delete anyone's saved views, tasks and exceptions |
- Everyone who signs in without a role entry is a User, and sees no findings until a grant applies to them.
- Roles and grants match the user's email or groups. The email must be trusted: asserted by
your SAML IdP, verified by your OIDC IdP (
email_verified), or marked verified in the Cognito user pool (Identity providers). - In Administration › Roles, choose User or Group, enter the email or the group name exactly as your IdP sends it (group names are case-sensitive), choose Administrator or User, and save. A role for a user wins over a role for one of their groups, so you can make a group administrators and keep one member a User. A change applies on the user's next request.
- You can't remove your own Administrator role. Grant it to at least one more person or group.
The bootstrap admin
BootstrapAdminEmail (a stack parameter) is the bootstrap admin. The first person who signs in
with that email is bound to it by their immutable user ID (the Cognito sub) and is always an
Administrator, which prevents lock-out. The Roles tab shows the entry as set by the stack. The binding
is recorded in the audit log (bootstrap.bind). Someone else who later signs in with the same email
address but a different user ID is not the bootstrap admin.
Recovering the bootstrap admin
Reset the binding when the bootstrap admin's user ID changes (the user was recreated, the IdP issues
a new subject, or you switched IdentityProvider). Either:
- Use a different person: update the stack and change
BootstrapAdminEmail. The first sign-in with the new email takes over the binding. - Keep the same email: update the stack with
BootstrapAdminEmailset to another address you can sign in with, and sign in with it once. Then set it back and sign in with the original email, which takes the binding over again.
If another Administrator can still sign in, they can simply grant the Administrator role to the person by email under Administration › Roles.
Connections
A connection is one IAM role Watchtower assumes in one AWS account that has AWS Security Hub, with the hub Regions it reads (Administration › Connections). Each connection and hub Region is a source that the sync worker indexes.
| Connection | Role | Set by |
|---|---|---|
Local (local) | The hub stack's role /watchtower/<NamePrefix>-local-<Region>, in the hub account | The stack: LocalAccessLevel and LocalRegions (empty means the stack's Region). It can't be changed or deleted in the portal |
| Spoke | A role created by the spoke role template (spoke-role.yaml) in another account, /watchtower/<RoleName> (watchtower-spoke by default). It trusts only the hub's API and sync roles, and only with your external ID | The spoke stack's AccessLevel, and the hub Regions you choose here |
Hub Regions
With cross-Region aggregation in your Security Hub delegated administrator account, a connection needs one hub Region: the aggregation Region. It holds the findings of every member account and every linked Region, and each finding still carries the Region where its resource lives. Without aggregation, list each Region where Security Hub runs; each becomes its own source.
Access levels
The access level of a connection's role is the ceiling for everyone, administrators included. Grants can narrow it per user or group but never widen it.
| Access level | Watchtower may | Permissions it allows |
|---|---|---|
Read (default) | Read findings, their history, standards and controls from Security Hub, and account names from AWS Organizations | view, fix |
Triage | Read plus changing the workflow status, notes and severity of findings (securityhub:BatchUpdateFindings) | plus triage |
fix doesn't need Triage: fix pull requests change your code on GitHub, never Security Hub or your
AWS resources. Use Read until your team triages in Watchtower. See
Read or Triage.
Add a connection
- Deploy the spoke role in the account
(installation guide). How to connect another
AWS account on the Connections tab shows the steps, the template URL and an AWS CLI command.
Set
HubApiRoleArnandHubSyncRoleArnto the hub stack'sApiRoleArnandSyncRoleArnoutputs and choose anExternalIdsecret of 16 or more characters. - Add a connection and enter:
- Id: a short name used in links and searches (
connection:security:eu-west-1), for examplesecurity. It can't be changed later. - Name and AWS account id.
- Access level: the same as the spoke stack's
AccessLevel. - Role ARN: the spoke stack's
RoleArnoutput,arn:aws:iam::<account>:role/watchtower/<RoleName>. It must be in that account and under the/watchtower/path. - External ID: the same secret you gave the spoke stack. It is stored and never shown again; when you edit the connection, leave it empty to keep it.
- Hub Regions: normally the aggregation Region.
- Id: a short name used in links and searches (
- Save, then test the connection. For each hub Region, the test assumes the role and reports whether Security Hub is enabled, the aggregation Region and its linked Regions (or that there is no cross-Region aggregation, so only that Region's findings are read), the enabled standards and a sample count of findings, or the AWS error.
The sync worker reads a new source within 5 minutes; to start at once, start a sync from the Sync tab.
Limits
| Starter | Team | Business | Enterprise | |
|---|---|---|---|---|
| Connections, the local one included | 2 | 10 | 50 | unlimited |
| Monitored AWS accounts | 10 | 50 | 250 | unlimited |
Monitored accounts are the distinct AWS accounts that findings belong to, across every source, the hub account included. With a delegated administrator, one connection can bring in every account of your organisation, and each counts. When there are more than your plan allows, Watchtower indexes the accounts with the lowest account ids first and skips the rest; the Sync tab lists the skipped accounts. Nothing is deleted in Security Hub.
Deleting a connection makes Watchtower stop using the role, and grants on it stop applying; the role stays in the account until you delete its stack. The local connection can't be deleted.
Grants
A grant gives a user or a group permissions on the findings of the AWS accounts matching some patterns, in some Regions (or all), on a connection (or all) (Administration › Grants). A new grant, or a change, applies on the user's next request.
| Field | Values |
|---|---|
| Subject | A user (their sign-in email) or a group (the name as your IdP sends it in the groups claim) |
| Connection | One connection, or All connections (including ones you add later) |
| Account patterns | One per line, up to 100: account ids with * (any run of digits) and ? (one digit), for example 111122223333, 1111* or * |
| Regions | Some Regions, or All Regions. This is the Region where the resource lives, not the aggregation Region |
| Permissions | Any of the table below |
| Description | Optional, for your records |
| Permission | Allows | Implies | Needs |
|---|---|---|---|
view | See the findings, their issues, Overview and Compliance counts, details, history, code matches and scanner correlations; create and edit tasks on them | ||
triage | Change workflow status, notes and severity in Security Hub; create exceptions over these accounts and Regions | view | a Triage connection |
fix | Preview fixes and open pull requests for these findings | view | Business plan and above |
Findings on global resources such as IAM roles carry the Region where Security Hub evaluated them (typically your home Region). Give teams that own IAM All Regions, or include that Region.
How grants combine
- A user's permissions are the union of every grant that matches them, through their email or any of their groups, capped by the connection's access level and the plan.
- Everything a user sees is computed from the findings they may view: search results, facet counts, the fix list, the Overview, Compliance, exports and details. A finding outside their grants is "not found", including in counts.
- A user can see a task when they created it, are its assignee, or may view at least one of its findings.
- Repositories and code scanner findings are visible to everyone signed in (they come from your own code); code matches are shown only on findings the user may view.
- Administrators have every permission everywhere, still bounded by each connection's access level and the plan.
Check access, on the Grants tab, shows the effective permissions of one person (by email and groups) on one connection, account and Region, what the connection's access level removes, and which grants matched.
How grants are enforced
AWS Security Hub has no permissions per member account: reading or updating findings acts on the whole hub, and returns or changes the findings of every member account. So Watchtower enforces account and Region grants itself, on every request: the index is filtered to the caller's grants on every read, and every finding in a change is checked before anything is sent to Security Hub.
AWS then bounds what each session may do. Every call to Security Hub runs with temporary
credentials (15 minutes) for the user, with their email as the SourceIdentity recorded in
CloudTrail, and, for non-administrators, a session policy for the action: reads only, or reads
plus securityhub:BatchUpdateFindings for someone with triage. A user without triage gets a
session that AWS refuses to let change findings, even if Watchtower's own check had a bug. And a
Read connection's role can't change findings at all.
Examples
| Goal | Grant |
|---|---|
The platform team triages every account starting 1111, in every Region | group platform-team, all connections, accounts 1111*, all Regions, triage |
| Auditors see everything and change nothing | group auditors, all connections, accounts *, all Regions, view |
| The payments team triages its two accounts, in Ireland only | group payments, connection security, accounts 111122223333 and 444455556666, Regions eu-west-1, triage |
| Developers of the sandbox accounts can open fix pull requests | group developers, all connections, accounts 7777*, all Regions, view fix |
| A contractor sees one account | user [email protected], connection security, account 111122223333, all Regions, view |
Integrations
Administration › Integrations holds the accounts Watchtower reads code from:
| Kind | Plan | Base URL | Authentication |
|---|---|---|---|
| GitHub | Team and above | https://api.github.com, or https://<host>/api/v3 for GitHub Enterprise Server | A fine-grained personal access token, or a GitHub App (app id, installation id and private key) |
| SonarCloud or SonarQube | Business and above | https://sonarcloud.io, or your SonarQube URL | A token; the organisation for SonarCloud |
Tokens and private keys are write-only: Watchtower stores them in AWS Secrets Manager as
<NamePrefix>/integrations/<id>, encrypted with the stack's key, and never shows, logs or audits
them. When you edit an integration, leave the secret empty to keep it. Test an integration to
check the token: it reports the GitHub login (and the scopes of a classic token) or the error.
Deleting an integration deletes its secret (with a 7-day recovery window in Secrets Manager) and is
refused while repositories use it.
The permissions to give the token or the app are in Code integrations.
Repositories
Team and above. Administration › Repositories lists the GitHub repositories whose Terraform and
CloudFormation Watchtower indexes and maps to findings: up to 10 on Team, 100 on Business, unlimited
on Enterprise. For each repository you choose the integration, the branch, the paths to index and to
exclude, the AWS accounts it deploys to, CloudFormation stack mappings, an optional SonarCloud project
and whether to run Trivy scans on it. The tab shows each repository's status (pending, indexing,
ok or error), the commit indexed and when, and how many files and resources it found. Index a
repository again at any time; otherwise it is indexed every 24 hours. Removing a repository deletes
its code index and scan results.
Everything about repositories, mapping, fixes and scanners is in Code integrations.
Ingest tokens
Business and above. CI pipelines upload SARIF or Trivy results to the stack's IngestUrl with an
ingest token instead of a user sign-in. In Administration › Ingest tokens, create a token with
a name, the repositories it may upload for (or all), and an expiry of 1 to 365 days.
- The token (
wti_followed by 40 characters) is shown once, when you create it. Store it as a CI secret, for exampleWATCHTOWER_INGEST_TOKEN. - Watchtower keeps only its SHA-256 hash and its first 8 characters, to recognise it in the list, with who created it, when it expires and when it was last used.
- Delete a token to revoke it at once. Every upload is audited (
scan.ingest).
Prefer one token per repository, and rotate them. See SARIF uploads from CI.
Sync
Administration › Sync shows every source (connection and hub Region):
| Column | Meaning |
|---|---|
| Status | ok, syncing, error or pending (not synced yet) |
| Last incremental, last full | When the source last synced |
| Findings | How many findings the index holds for it |
| Error | The last error, with the AWS error code; the previous index stays in use |
| Skipped accounts | Accounts beyond your plan's monitored accounts limit, not indexed |
| Next | When the next sync is due |
The sync worker runs every 5 minutes and syncs each source when it is due:
- incremental syncs read the findings updated since the last one, every 15 minutes by default;
- a full sync reads every active finding (and those archived within the closed findings period) every 24 hours by default, removes findings that no longer exist, and recomputes the compliance pass counts, account names, standards and controls.
You can start a sync of one source or of all, incremental or full; each is audited (sync.run). A
change made through Watchtower (workflow, note, severity) also starts an incremental sync of its
source. Findings beyond 500,000 per source are not indexed (closed and informational ones are dropped
first).
Settings
Administration › Settings:
| Setting | Default | Range | Meaning |
|---|---|---|---|
| Allowed IP ranges (CIDR) | empty (any network) | Business and above. One IPv4 or IPv6 range per line. People outside these ranges can sign in but can't use Watchtower. CI uploads to IngestUrl are not affected. A list that doesn't contain your own address is refused, so you can't lock yourself out | |
| Remediation SLA per severity (days) | critical 7, high 30, medium 90, low 180, informational 0 | 0 to 3,650 each | A finding is due this many days after it was first observed, and overdue while open after that. 0 means no SLA. Also sets tasks' default due dates |
| Incremental sync every (minutes) | 15 | 5 to 1,440 | Never faster than your plan: 60 minutes on Starter, 15 on Team, 5 on Business and Enterprise |
| Full sync every (hours) | 24 | 6 to 168 | |
| Keep closed findings (days) | 30 | 7 to 365 | How long closed findings stay in the index, for searches such as state:closed and for task progress |
| Longest exception (days) | 365 | 1 to 730 | The furthest ahead an exception may expire |
| Index repositories every (hours) | 24 | 1 to 168 | How often each repository's Terraform and CloudFormation is read again |
| Scan every (hours) | 24 | 6 to 720 | How often built-in Trivy scans run on each repository that has them, and SonarCloud results are pulled |
| Account names | empty | up to 5,000 names, 100 characters each | Names shown for account ids, overriding the names read from AWS Organizations (useful when the role can't read them, or for shorter names) |
Usage
Administration › Usage shows what Watchtower did over the last 30 days, per day: API calls, searches, sync runs, findings read from Security Hub, finding updates written, fix pull requests opened and scans run. Usage is kept for 400 days.
Audit log
Administration › Audit log lists events by UTC day, newest first, with the time, the actor, the action, the target and the source IP. Open an event for its details. Filter the page by text.
| Action | When |
|---|---|
bootstrap.bind | The bootstrap admin was bound to a user |
role.put, role.delete | A role was granted or removed |
connection.put, connection.delete | A connection was added, changed or deleted |
grant.put, grant.delete | A grant was added, changed or deleted |
settings.put | Settings were changed |
sync.run | Someone started a sync |
finding.update | Someone changed findings in Security Hub (how many, which fields, the first 20 findings) |
task.create, task.delete | A task was created or deleted |
exception.create, exception.update, exception.revoke | An exception was created, changed or revoked |
exception.apply | The sync worker suppressed findings for an exception, or set them back when it ended |
view.put, view.delete | A saved view was created, changed or deleted |
integration.put, integration.delete | An integration was added, changed or deleted (never the secret) |
repo.put, repo.delete | A repository was added, changed or removed |
fix.pr | Someone opened a fix pull request |
github.issue | Someone created a GitHub issue from a task |
scan.start | A Trivy scan was started |
scan.ingest | CI uploaded scan results with an ingest token |
ingest-token.create, ingest-token.delete | An ingest token was created or deleted |
licence.refresh | An administrator checked the licence |
update.available | A new release was found |
access.denied | A request was refused for a missing permission or an address outside the IP allowlist |
Events are kept for your plan's audit days: 30 on Starter, 90 on Team, 365 on Business and 3,650 on
Enterprise. Each event is also written to the API's CloudWatch log group,
/aws/lambda/<NamePrefix>-api, kept for the stack's LogRetentionDays, so you can forward it to your
SIEM.
For a full trail, CloudTrail in each connected account records every Security Hub call Watchtower
makes with sourceIdentity set to the user's email (or watchtower-sync for the sync worker) and the
role session name wt-<email>. Notes written to Security Hub carry the user's email as their author.
Licence and about
Administration › Licence and about shows your licence, your plan and the installed version.
Licence
Watchtower reads your AWS Marketplace licence from AWS License Manager in the hub account. The page shows the status, the plan, the entitlements, when the licence is valid until and when it was last checked. You can check the licence again at once (Watchtower otherwise rechecks every 10 minutes).
| Status | Meaning |
|---|---|
| Active | The licence is valid |
| Grace period | License Manager is unreachable, or an active licence disappeared (for example while you move between plans). The last active plan keeps working for 72 hours |
| Expired | The grace period ended without an active licence |
| No licence | The account has no Watchtower licence |
Without a valid licence every page except this one says a licence is required. Nothing is deleted; subscribing again unlocks Watchtower.
Plan
| Starter | Team | Business | Enterprise | |
|---|---|---|---|---|
| Monitored AWS accounts | 10 | 50 | 250 | unlimited |
| Connections | 2 | 10 | 50 | unlimited |
| Fastest sync | 60 minutes | 15 minutes | 5 minutes | 5 minutes |
| Trend history | 30 days | 90 days | 365 days | 730 days |
| Audit log kept | 30 days | 90 days | 365 days | 3,650 days |
| Saved views per user | 10 | 100 | 500 | unlimited |
| Code repositories | none | 10 | 100 | unlimited |
| Findings explorer with search, filters, grouping and private saved views; fix list with remediation guides; finding detail and history; triage written back to Security Hub; tasks with SLAs and progress; Overview, trends, mean time to remediate and Compliance; grants; connections; audit log; IAM Identity Center and Cognito sign-in | yes | yes | yes | yes |
| Shared saved views, exceptions, GitHub code mapping, GitHub issues from tasks, SAML and OIDC sign-in | yes | yes | yes | |
| Fix pull requests, Trivy, SonarCloud and SARIF scanners, IP allowlist | yes | yes |
Features your plan doesn't include show a plan badge, and Watchtower refuses them. To change plan, see Changing plan.
Version and updates
The version card shows the installed version and, when update checks are on (UpdateChecks), the
latest release, its summary and release notes, whether it is a security release, the oldest supported
version, and how to upgrade, with the template URL and an AWS CLI command. A banner on the
Administration pages announces a newer release once. See Upgrading.
Something unclear or missing? Email [email protected].