← Files SugerARCHIVED FILE

SKILL.md

16.9 KB · Oct 2, 2026 · 00:17 UTC

↓ Download file

---
name: gcp-integration-verify
description: "Verify GCP Marketplace integration end to end by reading expected values from the Suger Console settings page and then walking the GCP Console step by step with browser tools."
---

# Verify GCP Marketplace Integration

Use browser frontend tools only. Follow the exact step order below. Read and record every value as you go.

## Execution Contract

This flow has exactly **two** allowed reasons to pause, and exactly **two** allowed reasons to abort. Everything else continues without stopping.

- **Pause only for sign-in, and only if the page actually shows a sign-in form.** If the GCP Console is already loaded (project selector or home content visible), the user is already signed in — do not pause, do not ask, proceed. The only reason to pause is an active Google sign-in form on screen.
- **Abort in Step 4** when the GCP project welcome page cannot be accessed (project does not exist, or the user has no access to it).
- **Abort in Step 5** when the service account does not exist in the project (or the user has no access to the IAM service accounts page).
- **Every other outcome is a finding, not a stop.** Missing roles, wrong status, optional step failing, tool error — record it and move to the next step.

All browser tool calls used by this flow are pre-approved:

- `navigate` to any URL listed in a step is pre-approved. Call it directly. Do not ask the user before calling `navigate`. Do not stop on `navigate`.
- `extract_page`, `click`, `fill`, `list_tabs`, `get_ui_context` are all pre-approved.
- Do not invent new reasons to stop ("to be safe", "to confirm with the user", "just in case", "since the data is missing"). The only valid stops are the two pauses and the two aborts listed above.

## Pausing With Choices

Whenever you must pause (active sign-in screen, or a page still not loaded after retries), emit a message with **explicit short choices**, not a free-form question. The user should be able to continue by picking one option, not by typing a sentence.

Use this template:

> `<what is blocking>`. Choose one:
> - `Continue` — `<condition that lets the flow resume>`
> - `Skip` — skip this check and move on (only where the step explicitly supports skipping)
> - `Abort` — stop the verification now

When the user replies:
- `Continue` — call `extract_page` again and resume the step.
- `Skip` — record the current check as `skipped` and move to the next step.
- `Abort` — jump straight to the Reporting Format with results gathered so far.

Never say "please sign in and let me know when you are done" or ask the user to type a status update. Always offer the structured `Continue` / `Skip` / `Abort` choices.

## Core Rules

- Start each major step with `get_ui_context` or `list_tabs` so you know which page and tab you are operating on.
- Use `extract_page` before direct page actions such as `click`, `fill`, or `select`.
- Call `extract_page` again after every important transition (navigation, popup open, tab switch, pagination).
- GCP Console pages (IAM, Workload Identity, Pub/Sub detail) often load slowly. If `extract_page` returns a skeleton, a loading spinner, or a list that is clearly shorter than expected, wait a few seconds and call `extract_page` again. Retry at least five times. **Do not flag a check as failed while the page still looks like it is loading.** If after five retries the page is still not loaded, emit a `Continue` / `Skip` choice prompt (see "Pausing With Choices") instead of flagging the check.
- The only destinations this flow uses are Suger Console and `console.cloud.google.com` (plus `accounts.google.com` for sign-in). Inside that set, `navigate` needs no confirmation.
- Role names in GCP Console may appear with a `(Beta)` suffix (for example `Commerce Producer Admin (Beta)`). Treat `<Role>` and `<Role> (Beta)` as the same role for pass/fail purposes.
- Record every value you read (IDs, emails, role lists, bucket names, statuses). You will reuse them in the final report.

## Step 1: Open The Suger Integrations Settings Page

1. Use `get_ui_context` to determine whether the current environment is dev or prod from the hostname.
2. Use `navigate` to open the integrations settings page for that environment:
   - Dev: `https://console.dev.suger.io/settings?tab=integrations`
   - Prod: `https://console.suger.io/settings?tab=integrations`
3. Call `extract_page`.

## Step 2: Open The GCP Marketplace Integration Details

1. Locate the GCP Marketplace integration card on the settings page.
2. `click` the card's `Details` button to open the details popup.
3. In the popup, `click` the `Expand All` button.
4. Call `extract_page` to read the expanded, structured details.

## Step 3: Record Expected Values From Suger Console

Read and carry forward these fields from the details you just expanded:

- `gcpOrganizationId`
- `gcpProjectId`
- `gcpProjectNumber`
- `workloadIdentityPoolId`
- `identityProviderId`
- `serviceAccountEmail`
- `pubsubSubscription`
- `pubsubTopic`
- `reportBucket`

If any field is empty or missing, record it as `(not set)` and continue. Do not stop on missing optional fields here — later steps will handle them (for example Step 13 skips if `pubsubSubscription` is `(not set)`).

Derive and record these too:

- `serviceAccountName` = the part of `serviceAccountEmail` before the `@` character.
- `pubsubSubscriptionId` = the last path segment of `pubsubSubscription`. For example `projects/suger-private/subscriptions/suger-dev-suger-private` yields `suger-dev-suger-private`.

## Step 4: Confirm Project Is Accessible And Project Number Matches

1. Use `navigate` to open:
   - `https://console.cloud.google.com/welcome?project=<gcpProjectId>`
2. Call `extract_page`.
3. Decide which state the page is in:
   - **Already signed in** — the GCP Console welcome page renders with a `Project info` card. Continue.
   - **Sign-in form** — an `accounts.google.com` login page. Emit a `Continue` / `Abort` choice prompt. On `Continue`, call `extract_page` again and proceed.
   - **No access or project not found** — the page shows `Project not found`, `You don't have permission`, a 404, or redirects to the project picker. **Abort.** Tell the user: "`gcpProjectId` does not exist or the signed-in Google account has no access. Cannot continue verification." Jump straight to the Reporting Format with results gathered so far.
4. On the welcome page, read the `Project number` value in the `Project info` card and record it as `observedProjectNumber`.
5. Verify that `observedProjectNumber` equals `gcpProjectNumber`. Flag as a failure if they do not match, but continue.

## Step 5: Confirm Service Account Exists

1. Use `navigate` to open:
   - `https://console.cloud.google.com/iam-admin/serviceaccounts?project=<gcpProjectId>`
2. Call `extract_page`. If the page is still loading, follow the slow-load retry rule in Core Rules.
3. Search for a row whose email column equals `serviceAccountEmail`.
4. If the row exists, continue to Step 6.
5. If the row is not present after the list is fully loaded, or the page refuses to load with a permission error, **abort.** Tell the user: "Service account `serviceAccountEmail` does not exist in project `gcpProjectId`, or the signed-in account has no access to the IAM service accounts page. Cannot continue verification." Jump to the Reporting Format with results gathered so far.

## Step 6: Verify Service Account Project Roles

1. Use `navigate` to open:
   - `https://console.cloud.google.com/iam-admin/iam?project=<gcpProjectId>`
2. Call `extract_page`. Apply the slow-load retry rule until the principals list is fully rendered.
3. Locate the row whose principal equals `serviceAccountEmail`.
4. Record the set of roles on that row.
5. Verify that all of the following roles are present (treat `X` and `X (Beta)` as the same role):
   - `Commerce Price Management Private Offers Admin`
   - `Commerce Producer Admin`
   - `Consumer Procurement Entitlement Manager`
   - `Consumer Procurement Order Administrator`
   - `Editor` — `Viewer` is also acceptable in place of `Editor`.
   - `Pub/Sub Editor`
   - `Service Account Token Creator`
   - `Service Controller`
   - `Service Management Administrator`
   - `Workload Identity User`
6. Record the missing roles (empty list means all present). Flag the check as failed if any role from the list is missing, but continue.

## Step 7: Verify Workload Identity Pool Exists

1. Use `navigate` to open:
   - `https://console.cloud.google.com/iam-admin/workload-identity-pools?project=<gcpProjectId>`
2. Call `extract_page`. Apply the slow-load retry rule.
3. Confirm that a row whose ID (or name) equals `workloadIdentityPoolId` is present.
4. Record whether the pool exists. Flag as failed if not, but continue. If the pool is missing, still attempt Steps 8 and 9 (they will naturally fail at navigate time; record those as failures and continue).

## Step 8: Verify Workload Identity Provider

1. Use `navigate` to open:
   - `https://console.cloud.google.com/iam-admin/workload-identity-pools/pool/<workloadIdentityPoolId>?project=<gcpProjectId>`
2. Call `extract_page`. Apply the slow-load retry rule.
3. In the `Providers` section/list, confirm a row where **all** of the following hold:
   - `Display name` equals `suger`
   - `Type` equals `AWS`
   - `Status` equals `Enabled`
4. Record the provider row you observed (display name, type, status). Flag as failed if no row matches all three conditions, but continue.

## Step 9: Verify Connected Service Account

1. Remain on the workload identity pool detail page. `click` the `Connected service accounts` tab.
2. Call `extract_page`. Apply the slow-load retry rule.
3. Confirm that the list contains a service account whose name equals `serviceAccountName` (the part before the `@` in `serviceAccountEmail`).
4. Record whether the service account is connected. Flag as failed if not, but continue.

## Step 10: Verify gcpdev@suger.io Project Roles (Recommended, Not Required for Core Integration)

<!-- F8 note: These roles enable Suger-operated workflows (CPPO, resale support).
     The core marketplace integration works without them. Flag as advisory if missing. -->
1. Use `navigate` to open:
   - `https://console.cloud.google.com/iam-admin/iam?project=<gcpProjectId>`
2. Call `extract_page`. Apply the slow-load retry rule.
3. Locate the row whose principal equals `gcpdev@suger.io`.
4. Verify that all of the following roles are present (treat `(Beta)` as equivalent):
   - `Commerce Price Management Private Offers Admin`
   - `Commerce Producer Admin`
   - `Service Management Administrator`
   - `Viewer`
5. Record the missing roles. Flag as failed if any are missing, but continue.
6. If the `gcpdev@suger.io` row does not exist at all, record all four roles as missing and flag as failed, but continue.

## Step 11: Verify cloud-commerce-marketplace-onboarding Project Roles

1. Remain on the project IAM page from Step 10. Call `extract_page` again if needed.
2. Locate the row whose principal equals `cloud-commerce-marketplace-onboarding@twosync-src.google.com`.
3. Verify that both of these roles are present (treat `(Beta)` as equivalent):
   - `Editor`
   - `Service Management Administrator`
4. Record the missing roles. Flag as failed if any are missing, but continue.
5. If the row does not exist, record both roles as missing and flag as failed, but continue.

## Step 12: Verify Report Bucket Exists (Optional)

This step is optional. If it fails, the Notes section must tell the user Suger cannot ingest marketplace report data.

1. If `reportBucket` is `(not set)`, record this check as `skipped` with reason `reportBucket not configured` and continue to Step 13.
2. Use `navigate` to open:
   - `https://console.cloud.google.com/storage/browser?project=<gcpProjectId>&prefix=&forceOnBucketsSortingFiltering=true&bucketType=live`
3. Call `extract_page`. Apply the slow-load retry rule.
4. Confirm that a bucket whose name equals `reportBucket` is present in the list.
5. Record whether the bucket exists. Flag as failed if not, but continue.

## Step 13: Verify Pub/Sub Subscription (Optional)

This step is optional. If it fails, the Notes section must tell the user Suger cannot receive marketplace events.

1. If `pubsubSubscription` is `(not set)`, record this check as `skipped` with reason `pubsubSubscription not configured` and continue to Step 14.
2. Use `navigate` to open:
   - `https://console.cloud.google.com/cloudpubsub/subscription/detail/<pubsubSubscriptionId>?orgonly=true&project=<gcpProjectId>&supportedpurview=organizationId`
3. Call `extract_page`. Apply the slow-load retry rule. Do not conclude that the subscription does not exist until the detail page is fully loaded.
4. Verify that the subscription page exists (no "not found" message) and that:
   - `Subscription name` equals `pubsubSubscription`
   - `Topic name` equals `pubsubTopic`
   - `Status` equals `Active`
5. Record the observed subscription name, topic name, and status. Flag as failed if any of the three does not match, but continue.

## Step 14: Verify gcpdev@suger.io Organization Roles (Optional)

This step is optional. If it fails, the Notes section must tell the user Suger cannot help with resale.

1. If `gcpOrganizationId` is `(not set)`, record this check as `skipped` with reason `gcpOrganizationId not configured` and continue to the Report step.
2. Use `navigate` to open:
   - `https://console.cloud.google.com/iam-admin/iam?organizationId=<gcpOrganizationId>&supportedpurview=project`
3. Call `extract_page`. Apply the slow-load retry rule.
4. Locate the row whose principal equals `gcpdev@suger.io`.
5. Verify that all of the following roles are present (treat `(Beta)` as equivalent):
   - `Commerce Producer Admin`
   - `Commerce Business Enablement Configuration Admin`
   - `Commerce Business Enablement Reseller Discount Admin`
6. Record the missing roles. Flag as failed if any are missing, but continue.
7. If the `gcpdev@suger.io` row does not exist at the organization level, record all three roles as missing and flag as failed, but continue.

## Step 15: Report

Produce a concise verification summary using the Reporting Format below. The primary output is a Markdown table. Keep prose minimal.

## Reporting Format

Output in this exact shape.

**Header**

- Environment: dev or prod
- Project: `gcpProjectId` / `gcpProjectNumber`
- Service account: `serviceAccountEmail`

**Results table**

| # | Check | Status | Observed |
|---|---|---|---|
| 1 | Project accessible (Step 4) | pass / fail / aborted | welcome page state |
| 2 | Project number matches (Step 4) | pass / fail | expected `<gcpProjectNumber>`, got `<observedProjectNumber>` |
| 3 | Service account exists (Step 5) | pass / fail / aborted | found / not found |
| 4 | Service account project roles (Step 6) | pass / fail | missing: `[roles]` or `all present` |
| 5 | Workload Identity Pool exists (Step 7) | pass / fail | pool ID |
| 6 | Workload Identity Provider (Step 8) | pass / fail | display name / type / status |
| 7 | Connected service account (Step 9) | pass / fail | `serviceAccountName` found / not found |
| 8 | gcpdev@suger.io project roles (Step 10) | pass / fail | missing: `[roles]` or `all present` |
| 9 | cloud-commerce-marketplace-onboarding roles (Step 11) | pass / fail | missing: `[roles]` or `all present` |
| 10 | Report bucket exists (Step 12, optional) | pass / fail / skipped | bucket name or skip reason |
| 11 | Pub/Sub subscription (Step 13, optional) | pass / fail / skipped | name / topic / status or skip reason |
| 12 | gcpdev@suger.io org roles (Step 14, optional) | pass / fail / skipped | missing: `[roles]` or skip reason |

Status vocabulary:
- `pass` — check passed.
- `fail` — check failed. Add one bullet in the Notes section below.
- `skipped` — optional check was not run (input missing or load timeout).
- `aborted` — the whole flow stopped here (Step 4 or Step 5). No later rows were checked.

**Notes** (include only if the table has any `fail`, `skipped`, or `aborted` row)

One bullet per non-`pass` row. Keep each bullet to one line where possible:

- `<check>: expected <X>, got <Y>. <why it matters>. Fix: <action>.`

Additional notes required by the flow:

- If Step 12 or Step 13 is `fail` (or both are `fail` / `skipped`): add one bullet — `Suger cannot ingest marketplace reports or receive Pub/Sub events. Revenue, usage, and entitlement updates will not reach Suger until the report bucket and Pub/Sub subscription are fixed.`
- If Step 14 is `fail`: add one bullet — `Suger cannot help with resale. CPPO reseller private offer flows are blocked until the organization-level roles on gcpdev@suger.io are granted.`

**Conclusion** (one line)

- If every non-optional row is `pass` and no row is `aborted`: `GCP Marketplace integration appears correctly configured.` (Add `Optional checks: N skipped, M failed.` if any optional rows were not `pass`.)
- If any required row is `fail`: `<N> failures, <M> skipped. See notes above.`
- If the flow aborted: `Aborted at Step <X>: <one-line reason>. See notes above.`

Keep the report compact. Operational details belong in the per-failure Notes bullet, not in separate paragraphs.

SHA-256: f03cc1b56832a478aac3adbcc2889df84157abb5597d412399e8d5360e5c0890