Graine AI

Security log

Trace what your agents' security did — each check on a request, what it decided and why, and each change to the security settings, by whom — each row in full, filtered, a page at a time, and downloadable. Admins only.

The Security log shows each request your agent's security checked — which check, what it decided and why — and each change to the agent's security settings, newest first. Use it to trace what happened: your key in an app you don't know, an old app version that can't prove itself, a person who couldn't be verified, a switch someone turned off.

Where: Security → Security log for all your agents at once (the Overview tab shows the five latest rows, with Open the Security log). For one agent, Embed & Widgets → Install → Your app and your users → What we've seen, under the counts — with Open in the Security log to see that agent's rows on the full page. Only Admins can open it.

What each row shows

ColumnWhat it says
TimeWhen it happened, in your own time zone. Hover for the exact time in UTC.
AgentOn the Security log page, the agent the request was for. A change that serves every agent says Every agent.
CheckOnly my apps, Verified app, Verified user, Server token, Bot check, Key (a publishable key you revoked) or Allowed domains (a website the agent doesn't list).
ResultAllowed, Verified, Refused or Anonymous — or, while a switch is report-only, Would be refused (Would be anonymous for a person not yet proven in a chat or call). Hover for what it means.
WhyIn plain English — An app ID that is not listed, No server token, An expired identity token, The request didn't say which app it is — with ×N when it repeated (hover for when it last did).
AppThe app ID the app declared, or the website's address. Not sent when an app didn't say which app it is.
PlatformiPhone, Android, App or Website, with the SDK version when the request names it.
InstallA short one-way code for the app install or browser: the same install always shows the same code, and its ID is never shown.
WhereWhich part of the agent: Start-up, Chat or call, Call, Devices, Memory, Booking, Past conversations, App proof… and the country the request came from.

A change to the security settings is a row of its own: what changed, in a sentence — Turned on Only my apps, Added iPhone app com.acme.app (Team ABCDE12345), Revoked a publishable key, Changed allowed domains — and who made it, by name from your team and their role. Never a secret, a key or a token. A change that serves every agent, such as a Play Integrity key, shows in every agent's log.

One row in full

Click a row — or move to its time with Tab and press Enter — to open it in a panel beside the log (Esc closes it). For a check, the panel shows:

  • What this means and What to do — for every reason a row can carry, in plain English: The app named an app ID that isn't under Your apps. If it is your app, add its bundle ID or package name…
  • Details, each with its own label: when it happened, in your time and in UTC (for a row counted ×N, when it was first and last seen, and how many times); the check, the result and why; the switch at the time (Only my apps was on, Server tokens was report-only); the app, platform, SDK version, app version, install, where and country. And, when the request had them:
    • How the app proved itself — Apple App Attest, Google Play Integrity (with Google's verdict, such as recognised by Google Play, meets device integrity), a registered debug token (shown by the name it has in your settings today, or a debug token since removed), or an earlier proof on the same install — and whether it was a production or a development build.
    • How the person was proven — your sign-in's ID token (JWT), a signed user ID (HMAC), a token from your server, or a test user — with the exact reason a token was turned down: from another issuer, for another audience, expired, not valid yet, a bad signature, an unknown signing key, no user ID claim, a different user, or not readable. For an ID token, the sign-in issuer (its host) and the signing key (its key ID and algorithm).
    • Server token — the scopes the request needed, the scopes the token held, and the token's key ID.
    • Bot check provider — Cloudflare Turnstile or reCAPTCHA Enterprise.
    • Request ID and Answered with — the status the app or page received, such as 403 Refused or 200 OK. A row counted ×N also shows the latest request's ID and answer.
  • How it was decided — every check the request met, in order, each marked ✓ (passed), ✗ (refused), Report only or Anonymous.
  • Shortcuts — Show every row of this request, Everything from this install, Everything from this app and Everything from this check set the log's filters to that request, install, app or check; Open the agent's security settings; and Copy as JSON, the row exactly as it is kept (without the agent's or the person's name the page adds).

A change opens the same way: what changed, before → after for a switch or a value (Off → On, Report only → Enforce, 2 → 3), when, and who made it — their name from your team, their role and their member ID.

The app version shows only when the app sends one. Today the SDKs send it with a device's registration for calls (Devices), so rows from other parts of the agent don't have it.

Match a report to a row: the request ID

Every answer to a request the security checks see carries a response header, X-Graine-Request-Id — a 16-character code for that one request. It is the Request ID in the row's panel. When an app or a page reports a problem, note the code with the time: in a browser it is in the network tab, and readable by the page's own script; in an app, in your network logs. Paste the request ID from an error into the log's search box to find its rows — it is looked for across the whole year. A row counted ×N keeps the first request's ID and the latest one's.

How rows are grouped

  • A refused request is one row: the check that refused it. Nothing that request passed, and nothing report-only, is logged beside it. The same install refused again within a minute is counted on that row (×N).
  • A pass (Allowed, Verified) is one row per install and check every 10 minutes.
  • A report-only or anonymous result (Would be refused, Would be anonymous, Anonymous) is one row per install, check and reason every 10 minutes, whichever part of the agent it came from — the first is kept, the rest are counted on it (×N).
  • A request with no install — a website without one, or an app's start-up request before the app has proven itself — is grouped by the app ID or website instead, and shows no install code.
  • Under a flood, at most 60 new rows a minute of one kind, and 2,000 a day per agent, are added; the rest are counted on the latest matching row, and the first row of each kind in a day is always kept.

Filter, page and share

Filter by time (24 hours, 7 days, 30 days, 90 days or a year), everything, checks or changes, result, check, app ID or website (any part of it) and, on the Security log page, agent — type part of its name. Everything from this install in a row's panel filters to one install; remove it with the × on its chip. The filters are applied by Graine before anything is sent to your browser, and they stay as you move between pages; a new filter starts again at page 1.

A page holds 25, 50 or 100 rows. It says where you are — 1–50 of 312 — counted up to 10,000 (10,000+ past that), with Previous and Next. New rows arriving while you read don't move the page you are on.

The Security log page keeps its filters in its address — agent, time, kind, result, check, app ID, install, request ID and page size — so you can bookmark a view or send it to another Admin.

Download

Download CSV saves the current filter: up to 10,000 rows, newest first, times in UTC. A change names the member ID and role of whoever made it. Each download is recorded in the activity log.

How long, and what is never logged

Rows are kept for a year. If the log ever reaches its size limit, passing rows older than 30 days are removed first, so refusals and report-only rows stay for the year.

Never logged: IP addresses, user IDs, names, phone numbers, emails, identity tokens, server tokens, app proofs, publishable keys or any secret. An install is only ever its one-way code.

A row's detail adds codes and public facts only, and at most about 1 KB of them: a registered debug token's ID, never the token or its name (the panel looks the name up in your settings when you open the row); an ID token's issuer host and key ID, never the token or the person it names; a server token's scopes and key ID, never the token; Google Play's verdict words, never a device ID.

Next

On this page