Query QueryMesh on Behalf of Who Signed In
With the QueryMesh capability on, the application queries the organization's QueryMesh on behalf of the person who signed in. The credential is that person's, and the organization's data policies — access, masks and filters defined by governance — decide what they see. Two people, the same query, different results:
const r = await nn.querymesh.query(req, 'SELECT name, regionkey FROM tpch.tiny.nation')
// r.columns, r.rows — only what THIS person's policies let them see
The application does not provide the QueryMesh address, does not receive an IAM token and filters no rows.
Before You Start
- Organization sign-in turned on and deployed on the service.
- The organization's QueryMesh configured in Zero — the organization administrator does this once.
- You can change the service in the project.
- The console does not have the screen yet: use the CLI (or the API).
Step by Step
-
The organization administrator configures its QueryMesh, once:
zero orgs integrations set querymesh --url https://querymesh.yourcompany.comHTTPS only.
--audiencesays what QueryMesh requires in the token (defaulttrino-oidc). -
Turn the capability on in the service:
zero services enable querymesh webNo new deployment is needed: the capability becomes Pronta (ready) when the organization's IAM releases QueryMesh to the application.
-
Check it end to end:
zero services doctor querymesh webEach check says who fixes what is missing: the application, the organization administrator or the platform.
-
In your code, query with
nn.querymesh.query(req, sql).
In Your Code
import { NNumbers, QueryMeshAccessDeniedError, UnauthenticatedError } from '@nnumbers/zero/app'
const nn = NNumbers.init()
app.get('/api/countries', async (req, res) => {
try {
const r = await nn.querymesh.query(req, 'SELECT name, regionkey FROM tpch.tiny.nation ORDER BY name')
res.json({ columns: r.columns, rows: r.rows })
} catch (e) {
if (e instanceof UnauthenticatedError) return res.redirect(e.loginPath)
if (e instanceof QueryMeshAccessDeniedError) return res.status(403).json({ code: e.code })
throw e
}
})
query(req, sql, { maxRows, signal }) returns { columns, rows }, with the name and type of each column. Use full names (catalog.schema.table). maxRows (default 100,000) caps the rows brought into memory: above it, the query is cancelled in QueryMesh. signal cancels there too, not just the wait.
| Error | Code | When |
|---|---|---|
UnauthenticatedError | USER_SESSION_REQUIRED | nobody signed in, or the session ended — send them to loginPath |
ResourceCredentialError | RESOURCE_CREDENTIAL_DENIED | the capability or the organization's QueryMesh is off, or the IAM has not released QueryMesh yet — zero services doctor querymesh <service> says which |
QueryMeshIdentityRejectedError | QUERYMESH_IDENTITY_REJECTED | QueryMesh did not accept the person's identity — check the configured audience |
QueryMeshAccessDeniedError | QUERYMESH_ACCESS_DENIED | the data policies denied the query to this person |
QueryMeshError | QUERYMESH_QUERY_FAILED | syntax, missing table, maxRows exceeded; retryable when trying again may work |
In Another Language
The application asks for the person's credential at the address in NNUMBERS_BROKER_URL, with the identity it received on the request:
POST {NNUMBERS_BROKER_URL}/v1/credentials
X-NNumbers-Identity: <the request's identity>
Content-Type: application/json
{"resource": "querymesh"}
The response carries token, token_type (Bearer), expires_in (seconds) and resource.endpoint, the QueryMesh address. Query that address with the QueryMesh protocol and Authorization: Bearer <token>, and never send the token to another address. Check the identity first, as in Who Signed In, in Your Code: with no person, do not ask.
The States
| State | What it means | What to do |
|---|---|---|
| Desligada (off) | the capability is not on | — |
| Falta configurar na organização (missing organization setup) | the organization has no QueryMesh configured, or it is off | the organization administrator: zero orgs integrations set querymesh --url https://… |
| Aguardando o login da organização (waiting for organization sign-in) | organization sign-in is not ready for the application yet | turn on and deploy organization sign-in |
| Liberando o QueryMesh no IAM (releasing QueryMesh in the IAM) | the platform is releasing QueryMesh to the application | wait |
| O IAM não liberou o QueryMesh (the IAM did not release QueryMesh) | the organization's IAM does not accept QueryMesh for applications yet — once per organization | ask the platform administrator; it continues on its own afterwards |
| Pronta (ready) | the credential is issued on behalf of who signed in | — |
What the Platform Guarantees
- The query is the person's. The credential carries the identity of who signed in, issued by the organization's IAM for this application, and lasts minutes. With no person there is no query: there is no "application" credential to fall back to.
- The address is not the application's. It comes from the organization's configuration, and the credential only goes there. If QueryMesh says to continue at another address, the query fails and the credential does not follow.
- Turning off cuts immediately. Turning off the capability or the organization's QueryMesh makes the platform stop issuing the credential — even before the IAM finishes withdrawing the release.
- Everyone in their place. Another application, another organization, an ended session: no credential.
Limits
nn.querymeshis in the TypeScript SDK; in another language, use the call above.- One integration per organization: QueryMesh.
- The console does not have the screen yet: use the CLI or the API.
Next Steps
Was this page helpful?
Report a problem on this pageDo not send passwords, keys, tokens, or customer data.