Skip to main content

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​

  1. The organization administrator configures its QueryMesh, once:

    zero orgs integrations set querymesh --url https://querymesh.yourcompany.com

    HTTPS only. --audience says what QueryMesh requires in the token (default trino-oidc).

  2. Turn the capability on in the service:

    zero services enable querymesh web

    No new deployment is needed: the capability becomes Pronta (ready) when the organization's IAM releases QueryMesh to the application.

  3. Check it end to end:

    zero services doctor querymesh web

    Each check says who fixes what is missing: the application, the organization administrator or the platform.

  4. 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.

ErrorCodeWhen
UnauthenticatedErrorUSER_SESSION_REQUIREDnobody signed in, or the session ended — send them to loginPath
ResourceCredentialErrorRESOURCE_CREDENTIAL_DENIEDthe capability or the organization's QueryMesh is off, or the IAM has not released QueryMesh yet — zero services doctor querymesh <service> says which
QueryMeshIdentityRejectedErrorQUERYMESH_IDENTITY_REJECTEDQueryMesh did not accept the person's identity — check the configured audience
QueryMeshAccessDeniedErrorQUERYMESH_ACCESS_DENIEDthe data policies denied the query to this person
QueryMeshErrorQUERYMESH_QUERY_FAILEDsyntax, 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​

StateWhat it meansWhat 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 offthe 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 yetturn on and deploy organization sign-in
Liberando o QueryMesh no IAM (releasing QueryMesh in the IAM)the platform is releasing QueryMesh to the applicationwait
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 organizationask 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.querymesh is 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​