Skip to main content

Integrations and tests

This page explains how RiskFlow checks your Google Workspace for you: connecting it on the Integrations page, the Tests page that shows what was found, and how the results turn your controls red or green.

The idea in one minute​

  1. An admin connects Google Workspace once. The connection belongs to your team, not to the person who clicked Connect, so it keeps working without anyone being signed in.
  2. Every night RiskFlow reads your Google security settings and runs 48 tests on them (for example, "2-step verification is enforced"). An admin can also press Run now.
  3. Every result is saved. Tests shows each one as passing or failing, since when, and which org units fail. The Risk Assessment page shows the same saved results; it never calls Google itself.
  4. Each test is linked to one or more recommended controls. A failing test turns its control Failing on Controls, and a passing one turns it Passing. That is where green and red come from, and it feeds your readiness score.

Who can do what​

RoleIntegrations and tests
ORG AdminSee everything. Connect, reconnect, disconnect, Run now, excuse tests
ORG AuditorSee the status and the results. Read-only
Other ORG rolesNo access to Integrations. Roles with Controls or Risk Assessment access can read the results

Each team sees only its own integrations.

Connecting Google Workspace​

  1. Open Integrations.
  2. On the Google Workspace card, select Connect.
  3. Sign in to Google in the pop-up with a Workspace admin account on your organization's domain, and approve the read-only access.

RiskFlow asks for read-only access only: Cloud Identity policies and organizational units. It checks that the account can read your policies before saving anything.

The card then shows Connected, your domain, and who connected it and when.

Connect with an account that is meant to stay

RiskFlow keeps working if the person who connected leaves RiskFlow. It stops if their Google account is suspended or deleted, because Google then rejects the saved login. Connect with a long-lived admin account.

Statuses​

The card on Integrations shows one of these:

StatusMeaningWhat to do
ConnectedWorkingNothing
Needs reconnectGoogle rejected the saved login (password reset, account suspended, access revoked)An admin selects Reconnect
ErrorThe last check failed for another reasonSee the error on the card; it retries on the next run
DisconnectedYou disconnected itSelect Connect to start again

Reconnecting​

If the card says Needs reconnect, Google no longer accepts the saved login. This happens when the connecting account's password was reset, the account was suspended or deleted, or someone removed RiskFlow's access in the Google Admin console.

  1. An admin opens Integrations and selects Reconnect.
  2. Sign in to Google with a Workspace admin account and approve the read-only access again.

While the card says Needs reconnect:

  • the nightly run skips your team and Run now is not offered;
  • the last results stay visible on Tests, but they no longer count: the linked controls go back to Not started;
  • the audit log records when the connection broke.

After you reconnect, press Run now (or wait for the next night) and the controls fill in again.

The Tests page​

Tests lists every test with the team's latest result, worst first. Open a test to see what it checks, how to fix it in the Google Admin console, the org units that fail, the controls it feeds, and its last 90 results.

ResultMeaning
PassingThe setting matches best practice in every org unit
FailingAt least one org unit doesn't match. Shows "failing since" and which org units
ExcusedIt fails, but your team has excused it. See below
ErrorRiskFlow couldn't tell (for example, Google returned data it couldn't read). Counts as neither passing nor failing
Not run yetThe test hasn't run for your team

When the checks run​

Once Google Workspace is connected, RiskFlow checks it every night on its own. An admin can also start a check at any time with Run now (once every 5 minutes per team).

  • Every result is saved, so RiskFlow can say when a check started failing ("failing since Oct 3") and show the history.
  • If Google can't be reached or rejects the login, that run is marked failed and nothing is overwritten: the last good results stay as they were. The card shows the error, and the next nightly run tries again.
  • A check that changes between passing and failing is recorded in the audit log.

How checks turn controls red or green​

Each check is linked to one or more recommended controls (for example, "2-step verification is enforced" is linked to MFA enforced). After every run, RiskFlow updates those controls:

Latest result of a linked checkThe control
FailingTurns Failing
Passing, or excusedCounts it as passing
ErrorIgnores it
  • RiskFlow only uses a result if it is less than 48 hours old and the integration is Connected. The nightly run refreshes results every 24 hours, so one missed night is fine. Otherwise the check says nothing, so a broken connection never leaves a control green (or red) by mistake. A control with nothing checking it shows Not started.
  • So if the connection shows Error or Needs reconnect, its linked controls go back to Not started until the next good run.
  • Controls you wrote yourself (custom controls) are never changed by checks.
  • Every control status change is recorded in the audit log.

Excusing a check​

Sometimes a check fails for a good reason. For example, shared kiosk devices in their own org unit can't use 2-step verification. Someone who can manage controls can excuse the check:

  • for the whole check, or for one org unit only;
  • with a reason (20 to 2000 characters; auditors read it, like a control's N/A reason);
  • with an end date, at most 12 months away.

What happens:

  • The check shows Excused when an exception covers every failing org unit. If another org unit still fails, the check stays Failing and lists only that org unit.
  • An excused check counts as passing for its controls, so a control can stop being Failing right away. RiskFlow does not ask Google again; it re-reads the last result.
  • When the end date passes, the next nightly run ignores the exception and the check fails again (its "failing since" date starts over).
  • Removing an exception works the same way, at once.
  • Adding and removing exceptions are both recorded in the audit log, with who did it and the reason.

Disconnecting​

Disconnect tells Google to revoke RiskFlow's access (if Google can't be reached, RiskFlow still disconnects), erases the saved login, and records who did it in the audit log. Past results are kept, but they no longer count: controls linked to the checks go back to Not started.

If your team used the old Risk Assessment check​

Earlier versions of the Risk Assessment page asked whoever opened it to sign in to Google in their own browser tab. That per-person sign-in is gone, along with the saved logins behind it. Connect Google Workspace once on Integrations. The Risk Assessment page then fills in from the saved results after the first run.

For whoever deploys RiskFlow​

Saved logins are encrypted with INTEGRATION_ENCRYPTION_KEY (AES-256-GCM).

  • Generate it once: openssl rand -base64 32.
  • It is required in production. The API refuses to start without a valid key (32 bytes, base64), so set it on the API project before deploying this version. Locally it is only needed to connect an integration.
  • Set it with the Vercel REST API or dashboard, not vercel env add piped non-interactively (that stores an empty value), and check the value has no trailing newline.
  • Do not change or lose it. Credentials encrypted with the old key can't be read with a new one; every team would have to reconnect. Keep a copy in the team password manager.
  • Google OAuth must already be configured (GOOGLE_OAUTH_CLIENT_ID, GOOGLE_OAUTH_CLIENT_SECRET, GOOGLE_OAUTH_REDIRECT_URI). The Integrations pop-up uses that client and redirect URI.

The nightly checks run from Vercel Cron (/api/v1/internal/grc-tests, every 15 minutes, in apps/backend/vercel.json). Each call checks the teams whose last run is more than 24 hours old, oldest first, and stops starting new ones after about 4 minutes, so many teams spread across several calls. It needs CRON_SECRET set on the API project, like the training reminders.

The old Risk Assessment login. The user_tokens table, which held the old per-person Google logins in plain text, was dropped by migration drop_user_tokens. A team that used the old check connects once through Integrations instead.

See ADR 008 for the design.