GASP

Access Governance

The GASP twin gives every agent the same view of what metrics exist and how they connect, which is the reason to build one. Agents act on behalf of users, though, so the same agent has to show a sales rep and a CFO different numbers. This page is GASP's opinion on how to scope permissions in an agentic SaaS system with the policy engines you already run. It covers access to metric values. How the standard itself is maintained and changed is in GOVERNANCE.md.

The Problem

If every agent reads the same twin and every user can invoke any agent, then by default every user has access to every metric. A Support Manager's retention agent could ask the Finance twin for Customer Acquisition Cost (CAC). A sales rep's pipeline agent could read the pipeline of colleagues in other territories. Without governance the twin becomes a way around the access controls your security team has already built.

Enterprise access control is an old problem with well-tested answers: role and attribute policies, row-level security and delegated tokens. GASP's job is to give those answers a shared vocabulary for metrics.

The Three-Layer Model

Access control in an agentic system happens at three layers. Each one is enforced in a different place, so keep them separate when you design permissions.

1

Model Layer

Always visible

Every user can see what metrics exist, their canonical definitions, their relationships and their required fields. Treat the model as documentation: teams who cannot see it build shadow systems with duplicate definitions. A Support Manager should know what CAC is and where it lives in the graph, even if they cannot see the current number.

2

Computation Layer

Permission-gated

Whether a user can compute the current value of a metric is decided here, in the warehouse, through row-level security, column masking or a query rewriter. A query runs with the user's identity and permissions, so the warehouse makes the call rather than the agent.

3

Agent Layer

Delegated identity

Agents always act on behalf of a user and inherit that user's scope. A retention agent invoked by a Finance Manager sees different numbers than the same agent invoked by a Support Manager. Elevated service identities (board prep, compliance audit) are explicit, audited exceptions.

What GASP Adds

Two metric-level classifications give downstream policy systems stable identifiers to reference. They are recommendations for your own policy systems to enforce.

Sensitivity Tier

Aligns with ISO 27001, OSSA data_classification and AWS Cedar common patterns. See the glossary entry for the canonical definition.

Tier Description
public Shareable externally with no restriction (rare for internal SaaS metrics)
internal Shareable across the organization. Default for most operational metrics
confidential Cross-functional but sensitive. Typically restricted to managers and above
restricted Highly sensitive. Executive and finance-leadership only by default

Access Scope

Describes whether a metric is naturally filterable per user context (the ReBAC/ABAC dimension). See the glossary entry for the canonical definition.

Scope Description
unscoped Same value for everyone with access (e.g. company-wide ARR)
department-scoped Filtered by the viewer's department context
owner-scoped Visible only for records the viewer owns or manages (individual, team, territory, book or segment: interpretation lives in the adapter)

Recommended Classifications

Default sensitivity and scope for the 69 metrics in the GASP relationship graph. The other 244 metrics carry no recommendation yet; classify them with the decision framework below. Use these as a starting point. Your organisation's risk profile may justify different choices.

Metric Sensitivity Scope
Rule of 40 rule_of_40 restricted unscoped
Operating Margin operating_margin restricted unscoped
Free Cash Flow fcf restricted unscoped
Cash Burn Rate burn_rate restricted unscoped
Revenue per Employee revenue_per_employee restricted unscoped
Magic Number magic_number restricted unscoped
Employee Turnover Rate employee_turnover restricted unscoped
Employee NPS enps restricted unscoped
Pipeline Value pipeline_value confidential owner-scoped
Pipeline Coverage pipeline_coverage confidential owner-scoped
ACV acv confidential owner-scoped
Quota Attainment quota_attainment confidential owner-scoped
Win Rate win_rate confidential department-scoped
Forecast Accuracy forecast_accuracy confidential department-scoped
Cost per Lead cpl confidential department-scoped
Marketing Sourced Pipeline marketing_sourced_pipeline confidential department-scoped
Expansion Revenue Rate expansion_rate confidential department-scoped
Renewal Rate renewal_rate confidential department-scoped
Partner-Sourced Revenue partner_sourced_revenue confidential department-scoped
ARR arr confidential unscoped
MRR mrr confidential unscoped
ARPA arpa confidential unscoped
MRR Growth Rate mrr_growth_rate confidential unscoped
New MRR new_mrr confidential unscoped
Expansion MRR expansion_mrr confidential unscoped
Churned MRR churned_mrr confidential unscoped
Reactivation MRR reactivation_mrr confidential unscoped
New Customers new_customers confidential unscoped
Churned Customers churned_customers confidential unscoped
Contraction MRR contraction_mrr confidential unscoped
Net New MRR net_new_mrr confidential unscoped
NRR nrr confidential unscoped
GRR grr confidential unscoped
Gross Margin gross_margin confidential unscoped
Logo Churn Rate logo_churn_rate confidential unscoped
Revenue Churn Rate revenue_churn_rate confidential unscoped
CAC cac confidential unscoped
LTV ltv confidential unscoped
LTV:CAC Ratio ltv_cac_ratio confidential unscoped
CAC Payback Period cac_payback confidential unscoped
Marketing CAC marketing_cac confidential unscoped
Days Sales Outstanding dso confidential unscoped
Consumption Revenue consumption_revenue confidential unscoped
Usage Run-Rate usage_run_rate confidential unscoped
Prepaid Credit Balance prepaid_credit_balance confidential unscoped
ARR Including Usage Run-Rate arr_including_usage_run_rate confidential unscoped
Customer Health Score health_score internal owner-scoped
At-Risk Customer Rate at_risk_rate internal owner-scoped
Sales Cycle Length sales_cycle internal department-scoped
QBR Completion Rate qbr_completion internal department-scoped
CSAT csat internal department-scoped
First Response Time frt internal department-scoped
Ticket Volume ticket_volume internal department-scoped
Time to First Value ttfv internal department-scoped
Onboarding Completion Rate onboarding_completion internal department-scoped
Product Qualified Accounts pqas internal department-scoped
Deployment Frequency deployment_frequency internal department-scoped
MTTR mttr internal department-scoped
Total Customers total_customers internal unscoped
NPS nps internal unscoped
MQLs mqls internal unscoped
SQLs sqls internal unscoped
Lead Velocity Rate lvr internal unscoped
Self-Service Rate self_service_rate internal unscoped
Activation Rate activation_rate internal unscoped
Trial-to-Paid Conversion Rate trial_to_paid_conversion_rate internal unscoped
DAU/MAU Ratio dau_mau internal unscoped
Feature Adoption Rate feature_adoption internal unscoped
Uptime uptime internal unscoped

A Decision Framework

When classifying a new metric, work through three questions in order:

  1. Who needs it by default? If the answer is "the whole company," the tier is internal. If the answer is "managers and above," it is confidential. If it is "finance leadership and the CEO," it is restricted.
  2. Is it filterable? If the same metric makes sense with per-user context (my pipeline, my accounts, my team's tickets), give it a scope other than unscoped. A sales rep should see pipeline but only their own.
  3. Does computing it leak something the value alone does not? Aggregate marketing spend is less sensitive than per-campaign spend. Aggregate CAC is less sensitive than CAC broken down by channel. Publish the aggregate and restrict the breakdowns that expose competitive detail. Breakdowns are declared in the canonical formulas (CAC by cost centre, Win Rate by channel). The recommended tier and scope apply to the metric as a whole, so your policy can set a stricter tier on a breakdown.

Integration Patterns

GASP tags are metadata, read by the policy systems that do the enforcing. Four patterns cover most implementations.

Cedar Policies

Cedar is an open-source policy language used by AWS Verified Permissions and referenced in the OSSA governance schema. Express GASP classifications as resource attributes:

// Principal: User with department and clearance attributes
// Resource: GASP metric with sensitivityTier and accessScope

permit (
  principal in Department::"Finance",
  action == Action::"query",
  resource
)
when {
  resource has sensitivityTier &&
  resource.sensitivityTier in ["public", "internal", "confidential", "restricted"]
};

// Department managers see internal + confidential for their dept
permit (
  principal,
  action == Action::"query",
  resource
)
when {
  principal has role && principal.role == "manager" &&
  resource.sensitivityTier in ["internal", "confidential"] &&
  (resource.accessScope == "unscoped" ||
   resource.department == principal.department)
};

// Everyone sees internal + unscoped
permit (
  principal,
  action == Action::"query",
  resource
)
when {
  resource.sensitivityTier == "internal" &&
  resource.accessScope == "unscoped"
};

// Restricted tier: explicit allowlist only
forbid (
  principal,
  action == Action::"query",
  resource
)
unless {
  resource.sensitivityTier != "restricted" ||
  principal in Group::"FinanceLeadership"
};

Open Policy Agent (Rego)

OPA is a CNCF graduated policy engine and a common choice for policy-as-code in large companies. The same GASP classifications expressed in Rego:

package gasp.authz

import rego.v1

default allow := false

# Everyone sees internal + unscoped metrics
allow if {
  input.resource.sensitivityTier == "internal"
  input.resource.accessScope == "unscoped"
}

# Department managers see confidential within their department
allow if {
  input.principal.role == "manager"
  input.resource.sensitivityTier in {"internal", "confidential"}
  manager_can_see_scope
}

manager_can_see_scope if input.resource.accessScope == "unscoped"
manager_can_see_scope if {
  input.resource.accessScope == "department-scoped"
  input.resource.department == input.principal.department
}
manager_can_see_scope if {
  input.resource.accessScope == "owner-scoped"
  input.resource.owner == input.principal.user_id
}

# Restricted requires explicit finance leadership membership
allow if {
  input.resource.sensitivityTier == "restricted"
  "finance_leadership" in input.principal.groups
}

Warehouse Row-Level Security

Row-level security is where enforcement reaches the data. Snowflake, BigQuery and Postgres all support it, filtering the result set by the user's identity. You can generate the policies from GASP classifications.

-- Snowflake: owner-scoped pipeline visibility
-- "Owner" can be an individual rep, a territory, a book or a segment.
-- Interpretation lives in the ownership_assignments table, not in GASP.
CREATE ROW ACCESS POLICY pipeline_owner_policy AS (owner_id VARCHAR)
  RETURNS BOOLEAN ->
    CASE
      WHEN CURRENT_ROLE() IN ('SYSADMIN', 'FINANCE_LEADERSHIP') THEN TRUE
      WHEN CURRENT_USER() IN (
        SELECT user_id FROM governance.ownership_assignments
        WHERE assigned_owner_id = owner_id
      ) THEN TRUE
      ELSE FALSE
    END;

ALTER TABLE fct_opportunities
  ADD ROW ACCESS POLICY pipeline_owner_policy ON (owner_id);

-- BigQuery: restricted-tier column masking via data policy
CREATE OR REPLACE TABLE company_metrics OPTIONS (
  policy_tags_on_columns = [
    ('burn_rate',  'projects/acme/locations/us/taxonomies/gasp/policyTags/restricted'),
    ('operating_margin', 'projects/acme/locations/us/taxonomies/gasp/policyTags/restricted')
  ]
);

MCP OAuth Scopes

An agent always acts on behalf of a user and inherits that user's scope through a delegated identity. The 23 GASP MCP tools return model-layer information, SQL text and Ossie documents; the only values they compute come from GASP's synthetic dataset, so one read scope covers them all. Gate the tool that runs SQL against your warehouse instead: map GASP sensitivity tiers to OAuth scopes on that executor and let warehouse row-level security apply the access scope.

// OAuth scopes: one read scope for the GASP MCP tools.
// run_query is your SQL executor, the only tool that returns values;
// each metrics:query scope admits metrics of that GASP sensitivity tier.
{
  "scopes": {
    "gasp:read": ["lookup_metric", "lookup_definition", "list_metrics",
                  "get_formula", "get_relationships", "get_data_requirements",
                  "search", "generate_query", "validate_mapping", "validate_adapter",
                  "compile_model", "score_drift", "profile_schema", "propose_mapping", "record_decision", "derive_cel", "generate_checks", "plan_fixes", "infer_drivers", "explain_path", "coverage_gap"],
    "metrics:query:public":       ["run_query"],
    "metrics:query:internal":     ["run_query"],
    "metrics:query:confidential": ["run_query"],
    "metrics:query:restricted":   ["run_query"]
  },
  "role_scopes": {
    "ic":       ["gasp:read", "metrics:query:public", "metrics:query:internal"],
    "manager":  ["gasp:read", "metrics:query:public", "metrics:query:internal",
                 "metrics:query:confidential"],
    "exec":     ["gasp:read", "metrics:query:public", "metrics:query:internal",
                 "metrics:query:confidential", "metrics:query:restricted"]
  }
}

Agent Integration Patterns

The protocols covered above handle single-user data access. Agentic systems add a second identity layer: agents act on behalf of users but have their own permissions too. OSSA (agent contracts) and A2A (inter-agent communication) meet GASP at that second layer.

The Three-Ceiling Model

A common mistake in agentic systems is letting agents run with service accounts that have more access than the user who invoked them. Effective access is the intersection of three ceilings:

effective_access = min(agent_clearance, user_clearance, metric_sensitivity)
  • Agent clearance comes from the OSSA manifest (authorization.clearance_level)
  • User clearance comes from your identity provider (Okta, Google Workspace, Azure AD)
  • Metric sensitivity comes from GASP (accessControl.classifications)

The warehouse enforces the intersection through row-level security and column masking. The agent and the application describe the constraints and the warehouse computes the answer.

Token Propagation (A2A)

When a coordinator agent calls a specialist via A2A, the user's token must propagate through the call chain. If the coordinator uses its own service token, privilege escalates silently. The pattern is OAuth 2 Token Exchange (RFC 8693):

// Coordinator receives a request with the user's token
// It does NOT use its own service token to call specialists

// 1. Coordinator exchanges the user token for a delegated token
//    scoped to the specialist audience
POST /oauth/token
Content-Type: application/x-www-form-urlencoded

grant_type=urn:ietf:params:oauth:grant-type:token-exchange
&subject_token=
&subject_token_type=urn:ietf:params:oauth:token-type:access_token
&audience=https://agents.acme.com/retention-specialist
&actor_token=
&actor_token_type=urn:ietf:params:oauth:token-type:access_token
&scope=gasp:read metrics:query:confidential

// 2. Coordinator calls the specialist with the delegated token
POST https://agents.acme.com/retention-specialist
Authorization: Bearer 
Content-Type: application/json

{
  "jsonrpc": "2.0",
  "id": "req-coord-001",
  "method": "SendMessage",
  "params": { "message": { "messageId": "msg-coord-002", "role": "ROLE_USER", "parts": [...] } }
}

// The specialist now executes warehouse queries with the ORIGINAL user's
// identity. If the user cannot see restricted metrics, neither can the
// specialist acting on their behalf. No privilege escalation via chaining.

Human Review for Restricted Access (OSSA)

OSSA's governance.authorization marks which tools need a human approval and which policies the agent must follow. Together with a policy that reads the GASP tier tag, this is a cheap safety valve for the restricted tier:

# In the agent's .ossa.yaml manifest
apiVersion: ossa/v0.5.6
kind: Agent
metadata:
  name: gasp-retention-analyst

governance:
  authorization:
    clearance_level: 3          # handles up to confidential on its own
    tool_permissions:
      - tool: lookup_metric     # reads the twin: never gated
        risk_level: low
        requires_approval: false
      - tool: run_query         # your SQL executor
        risk_level: high
        requires_approval: true # the runtime pauses for a reviewer
    policy_references:
      - gasp.restricted_metrics_require_review   # approves unless a metric is restricted

cognition:
  governance:
    audit_required: true
  alignmentGate:
    enabled: true
    arbiter: human
    timeout: 4h

When the retention agent, asked to explain a Net Revenue Retention (NRR) drop, requests Burn Rate (a restricted metric) for context, the OSSA runtime pauses the query and asks a reviewer in Finance Leadership. The user sees "waiting for review" rather than getting the number silently. The manifest says only that the query tool is approval-gated. The referenced policy decides when, and all it has to compare is the GASP tier tag on the metrics in the request, so a query over public and internal metrics goes straight through. OSSA's own human_review_triggers fire on reasoning signals (low confidence, a contradiction, branch depth), so the tool gate lives in governance.authorization instead.

The Audit Tuple Requirement

Traditional warehouse audit logs capture one identity: whoever ran the query. In agentic systems you need three: the user who asked, the agent that ran and the session that connected them. With only the first, the day an agent does something unexpected you can see the query but cannot tell who asked for it.

-- Extend warehouse queries to carry the full identity tuple
-- Snowflake query tag example
ALTER SESSION SET QUERY_TAG = OBJECT_CONSTRUCT(
  'user_id',     'user-sarah-cfo',
  'agent_id',    '[email protected]',
  'session_id',  'a2a-ctx-abc-123',
  'parent_task', 'task-coord-001',
  'gasp_metric', 'nrr',
  'tier',        'confidential'
)::STRING;

-- Then correlate across four log sources:
--   1. Identity provider (user authentication)
--   2. A2A message log (agent invocations)
--   3. MCP server log (tool calls)
--   4. Warehouse query log (actual data access)
-- Joined on session_id, you get the complete chain from
-- "user Sarah asked a question" to "specifically these rows were read".

OSSA and A2A have no standard audit format yet. GASP recommends propagating the tuple on every call, joining the four logs on session_id and keeping them as long as your compliance framework requires (typically 90 to 365 days).

Who Does What

Concern Owner Where it is configured
Metric sensitivity classification GASP accessControl.classifications in ontology
Agent clearance ceiling OSSA authorization.clearance_level in agent manifest
User identity and role Identity provider Okta, Google Workspace, Azure AD
Token propagation between agents A2A OAuth 2 Token Exchange (RFC 8693)
Human-in-the-loop gates OSSA governance.authorization.tool_permissions with requires_approval
Policy evaluation Cedar / OPA Policy-as-code referencing GASP tier tags
Row-level and column enforcement Warehouse Snowflake RLS, BigQuery policy tags, Postgres RLS
Audit logging Identity + A2A + MCP + Warehouse Propagate (user, agent, session, task) tuple through all four

Common Dilemmas

The Support Manager and CAC

A Support Manager wants to understand CAC to argue that reducing support friction lowers churn and improves unit economics. GASP tags CAC as confidential and unscoped. Should they see it?

Recommended resolution: Yes, in aggregate. A Support Manager should see company-level CAC as part of operating context. They should not see CAC broken down by channel, by quarter or by campaign, because those cuts show where and how hard the company is spending to win customers.

Board Prep Agent and Restricted Metrics

The board deck needs burn rate, runway and operating margin. Burn rate and operating margin are restricted. Runway is derived from the cash balance and burn rate. Should an automated agent be able to pull these?

Recommended resolution: Yes, through an explicit service identity with elevated scope. The agent runs as a governance-approved service account with its own audit trail, so when the CFO invokes it, its permissions come from that account rather than from the CFO. Every invocation is logged, the same pattern as a CI pipeline with elevated deployment permissions.

Cross-Functional Dashboards

A company-wide health dashboard shows NRR, Gross Margin and Employee Net Promoter Score (eNPS). NRR and Gross Margin are confidential and eNPS is restricted, so the panels have two different audiences. How should this be governed?

Recommended resolution: The dashboard renders what each viewer is allowed to see. A department manager sees NRR and Gross Margin but the eNPS panel is masked or hidden. Everyone runs the same dashboard code and the warehouse filters per viewer through the row-level policies above, so the dashboard needs no permission logic of its own.

What about agents that call other agents?

A coordinator agent invokes a Finance specialist agent to compute Rule of 40. The coordinator was invoked by a Sales Manager. Whose permissions apply?

Recommended resolution: Always the originating human identity. Protocols like A2A propagate the caller token. The Finance specialist executes the query with the Sales Manager's credentials, which hit the warehouse's row-level policies. If the Sales Manager cannot see restricted metrics, neither can any agent acting on their behalf.

What GASP Does Not Do

GASP is a standard, not a runtime. Specifically:

  • GASP does not enforce permissions. Enforcement belongs in Cedar, OPA, your identity provider or your warehouse.
  • GASP does not define user roles. Your organisation designs its own role hierarchy and GASP gives those roles a vocabulary to reference.
  • GASP does not audit access. Audit logging happens where queries run (the warehouse) and where tokens are issued (the identity layer).
  • GASP does not replace your data governance program. It complements SOC2, ISO 27001 and existing compliance frameworks.

GASP adds the shared vocabulary. Once every metric has a stable ID, a recommended tier and a recommended scope, policies move between tools: a Cedar policy written against GASP metric IDs works the same on Snowflake or BigQuery, with Okta or Google Workspace as the identity provider.

Try searching for:

↑↓navigate↵select