Connect your systems: the context endpoint
Give GaaS one HTTPS address of your own. When your agent proposes an action, GaaS asks that address for the facts its policies check (is the channel encrypted, is there an active security incident, has the customer consented, what is this agent's spending limit) and decides with them. You answer from your own systems, in one small JSON shape.
Why it matters
Policies decide on facts. When GaaS has no source for a fact, it treats the gap as risk: the context is reported as missing, confidence drops, and a policy that needs the fact to allow an action does not allow it. For example, pol_t1_001 blocks sending payment-card data unless environmental.channel_encryption is true. Your endpoint is how GaaS learns facts only you know.
How it works
| When | During every decision for your organization, in live, shadow and test mode, for the categories you chose that matter to the action (below). One request per decision. |
| What GaaS sends | A signed POST describing the action: agent, action type and verb, target, sensitivity, estimated impact and the context your agent declared. Never the action's free-text summary or content. |
| What you answer | The facts you know, per category. Every fact is optional; leave out what you don't know. |
| Time limit | One attempt, within your endpoint's time limit: 1.5 seconds by default, 200 ms to 3 seconds. No retries, and redirects are not followed. |
| If it fails | The decision still happens. The categories it should have answered count as missing context, which is risk, and the audit record says why (below). |
Which categories GaaS asks for
You choose which of the six categories your endpoint answers. For each action GaaS asks only for those that matter to it:
| Category | Asked when |
|---|---|
environmental | Always |
entity_state | The action is transact, access, modify or control |
regulatory | The target is regulated, or the agent declared regulatory domains |
organizational | The action has financial exposure, or the agent is not certified |
identity | The action is access, modify or control |
security | The target is not public, or the action has financial exposure |
GaaS keeps its own history, behaviour and session-trust context; those categories are not asked for.
Set it up
In the dashboard: Settings → Connected systems. Only an organization admin who signed in with two-factor can change it. Enter the address, choose the categories, and give the secret your endpoint expects, if any (sent as Authorization: Bearer … or in a header you name). GaaS then shows you a signing secret, once: store it, because your endpoint uses it to check that requests come from GaaS. Press Test connection; when every category answers correctly you can switch the endpoint on. Changing the address, categories, secret or time limit switches it off until you test again.
The same with the API (admin key to change, operator or admin key to read):
| Endpoint | What it does |
|---|---|
GET /v1/context-endpoint | Your settings. Secrets appear only as their last four characters. |
PUT /v1/context-endpoint | Create or replace: url, categories, auth_type (none, bearer, header), auth_header_name, auth_secret (write-only; omit to keep), timeout_ms, enabled. The first save returns the signing_secret, once. |
POST /v1/context-endpoint/test | Sends a signed test request ("test": true, "mode": "test") and reports each category. At most 6 a minute. |
POST /v1/context-endpoint/rotate-signing-secret | A new signing secret, returned once, used from the next request. |
DELETE /v1/context-endpoint | Remove it. Decisions go on without it at once. |
?mode=shadow: GaaS calls your endpoint and records what it would decide, without enforcing anything. Compare the verdicts and the audit records before you rely on it in live.
The request
| Header | Value |
|---|---|
Content-Type | application/json |
X-GaaS-Request-Id | Unique per request, also in the body as request_id |
X-GaaS-Timestamp | Unix seconds when GaaS signed the request |
X-GaaS-Signature | v1= + hex HMAC-SHA256 of <timestamp>.<raw body> with your signing secret |
Authorization or your header | The secret you saved, if any |
{
"contract_version": "1",
"request_id": "ctxreq_5f0c2a9e41d7b3a8c6e2f190",
"sent_at": "2026-09-29T15:04:05.123456Z",
"mode": "live",
"test": false,
"categories": [
"environmental",
"regulatory"
],
"intent": {
"id": "8c1e1a4e-3f7a-4d8e-9f10-2b7c5d6e7f80",
"agent": {
"id": "billing-agent",
"name": "Billing agent",
"framework": "langchain"
},
"action": {
"type": "communicate",
"verb": "send_email",
"target": {
"type": "person",
"identifier": "cust_42",
"sensitivity": "confidential",
"jurisdiction": "US-CA"
},
"estimated_impact": {
"reversible": true,
"financial_exposure_usd": 0,
"audience_size": 1,
"data_categories": [
"PCI"
],
"regulatory_domains": [
"PCI-DSS"
]
}
},
"context_provided": {
"session_id": "sess_19",
"user_state": null,
"environment": {
"channel": "email"
}
}
}
}
Full schema: context-endpoint-request.v1.json.
Verify the signature
Check every request before you answer it. Reject a timestamp more than five minutes from your clock, so a recorded request cannot be replayed. Python, standard library only:
import hashlib, hmac, time
def verify(secret: str, headers: dict, body: bytes) -> bool:
"""True only if GaaS signed this exact body within the last five minutes."""
lower = {k.lower(): v for k, v in headers.items()}
timestamp = lower.get("x-gaas-timestamp", "")
signature = lower.get("x-gaas-signature", "")
if not timestamp.isdigit() or abs(time.time() - int(timestamp)) > 300:
return False
expected = "v1=" + hmac.new(secret.encode(), timestamp.encode() + b"." + body, hashlib.sha256).hexdigest()
return hmac.compare_digest(expected, signature)
The response
Answer 200 with Content-Type: application/json:
{
"contract_version": "1",
"facts": {
"environmental": {
"channel_encryption": true,
"tls_version": "1.3",
"protocol": "https"
},
"regulatory": {
"applicable_frameworks": {
"PCI-DSS": {
"level": 1
}
},
"cardholder_data_environment": false
}
},
"as_of": {
"environmental": "2026-09-29T15:04:00Z",
"regulatory": "2026-09-29T00:00:00Z"
}
}
- Put each category's facts under
facts.<category>. Answer every category GaaS asked for; an empty object is fine. as_ofis optional: when each category's facts were last true, with a time zone. Old facts count as stale context.- A fact with the wrong type fails its whole category (the others still count).
nullmeans "not known". - Keys that are not in the table below are kept, so your organization's own policies can read them. Keys are lower case, letters, digits and
_; at most 200 per category, nested at most five levels. - The whole answer must be at most 256 KB.
Full schema: context-endpoint-response.v1.json.
The facts GaaS's policies read
This is every fact a built-in policy checks. Supply the ones you can; a policy that does not get the fact it needs treats it as missing.
| Category | Fact | Type | Meaning |
|---|---|---|---|
environmental | channel_encryption | boolean | The channel the action uses is encrypted end to end. |
environmental | tls_version | string or number | TLS version of that channel, e.g. "1.3". |
environmental | protocol | string | Transport protocol, e.g. "https", "sftp", "ftp". |
environmental | network_segment | string | Network segment the target sits in, e.g. "cde", "internal", "public". |
environmental | global_privacy_control | boolean | The consumer sent a Global Privacy Control signal. |
environmental | communication_channel | string | Channel for an outbound communication: "voice", "sms", "email", …. |
environmental | communication_method | string | How it is placed, e.g. "autodialer", "prerecorded", "ai_voice", "manual". |
environmental | recipient_local_hour | integer | Recipient's local hour, 0–23. |
environmental | recipient_state | string | Recipient's US state, two letters, e.g. "FL". |
environmental | ai_voice_detected | boolean | The call uses an AI-generated voice. |
environmental | ai_voice_disclosure | boolean or string | The call discloses that the voice is AI-generated. |
environmental | boundary_crossing_approved | boolean | Data leaving the FedRAMP authorization boundary is approved. |
environmental | encryption_standard | string | Encryption module standard, e.g. "fips_140_3". |
environmental | transport_security | string | Transport security for CUI, e.g. "tls_1_3", "fips_validated". |
entity_state | account_balance_usd | number | Current balance of the account the action touches, in USD. |
entity_state | account_status | string | Status of that account, e.g. "active", "frozen", "closed". |
regulatory | applicable_frameworks | object | Frameworks that apply, keyed by domain, e.g. {"PCI-DSS": {...}}. |
regulatory | gdpr_consent | object | The data subject's GDPR consent record.status: "active" | "withdrawn" | … |
regulatory | hipaa_access_purpose | string | HIPAA purpose of the access: "treatment", "payment", "operations", "research", …. |
regulatory | patient_authorization | boolean | A documented patient authorization covers this use. |
regulatory | minimum_necessary_override | string or boolean | Documented reason to override minimum necessary (e.g. emergency care). |
regulatory | patient_access_request | object | A patient's right-of-access request being answered.response_deadline_days: number, extension_granted: boolean, elapsed_days: number, denial: boolean, denial_reason: string |
regulatory | cardholder_data_environment | boolean | The target is inside the cardholder data environment. |
regulatory | ccpa_opt_out | object | The consumer's CCPA sale/share opt-out.status: "opted_out" | … |
regulatory | consumer_age | number | The consumer's age in years. |
regulatory | ccpa_minor_opt_in | object | Opt-in for a consumer under 16.status: "active" | …, consent_source: "parent_guardian" | "self" |
regulatory | gpc_override_consent | object | Consent that overrides a Global Privacy Control signal.status: "active" | … |
regulatory | ferpa_record_type | string | Kind of education record, e.g. "grades", "directory_information". |
regulatory | ferpa_consent | object | Written consent to disclose the education record.status: "active" | … |
regulatory | ferpa_disclosure_purpose | string | FERPA exception relied on, e.g. "school_official", "judicial_order". |
regulatory | ferpa_directory_opt_out | boolean | The student opted out of directory-information disclosure. |
regulatory | sox_scope | object | The action is in SOX scope.action: "approve" | "certify" | …, initiated_by: string, reporting_period: string, control_override: boolean |
regulatory | tcpa | object | TCPA context, when kept together.communication_channel: string, tcpa_consent: object (as tcpa_consent) |
regulatory | tcpa_consent | object | The recipient's TCPA consent record.status: "active" | "revoked" | …, consent_type: "prior_express_written" | "prior_express" | "oral" | …, consent_form_valid: boolean, pewc_elements: object, revocation_requested_at: ISO 8601 string, revocation_processed_at: ISO 8601 string |
regulatory | dnc_registry_status | string | National Do Not Call status of the number, e.g. "listed", "not_listed". |
regulatory | established_business_relationship | object | An established business relationship with the recipient.status: string, last_transaction_date: ISO 8601 date, last_inquiry_date: ISO 8601 date |
regulatory | dnc_last_scrub_date | string | When the list was last scrubbed against the DNC registry (ISO 8601 date). |
regulatory | internal_dnc_listed | boolean | The number is on your own do-not-call list. |
regulatory | revocation_sla_exceeded | boolean | A consent revocation was not processed within its deadline. |
regulatory | revocation_business_days_elapsed | number | Business days since the revocation request. |
regulatory | ai_voice_detected | boolean | The call uses an AI-generated voice. |
regulatory | ai_voice_disclosure | boolean or string | The call discloses that the voice is AI-generated. |
regulatory | recipient_state | string | Recipient's US state, two letters. |
organizational | delegation_limit_usd | number | The most this agent may commit on its own, in USD. |
organizational | gdpr_legal_basis | string | GDPR Article 6 basis, e.g. "contract", "legitimate_interest". |
organizational | legitimate_interest_assessment | string or boolean or object | A documented legitimate-interest assessment. |
organizational | phi_access_scope | string or array | The documented scope of PHI this agent may access. |
organizational | bulk_access_justification | string | Why bulk access to PHI is needed. |
organizational | ssl_certificate_valid | boolean | The target's TLS certificate is valid. |
organizational | certificate_expiry_days | number | Days until that certificate expires. |
organizational | pci_network_segmentation | string | "compliant" or "non_compliant". |
organizational | legitimate_educational_interest | boolean | The requester has a legitimate educational interest. |
organizational | ferpa_annual_notice_issued | boolean | The annual FERPA directory-information notice was issued. |
organizational | sox_audit_trail | object | Audit trail for SOX-relevant actions.status: "active" | … |
organizational | sox_management_certification | object | Management certification.period: string, status: "certified" | … |
organizational | sox_override_authorization | object | Authorization for a SOX control override.status: "approved" | … |
organizational | risk_management_system | string or boolean | An AI risk-management system is in place (EU AI Act Art. 9). |
organizational | risk_framework_ref | string | Reference to that risk framework. |
organizational | training_data_lineage | string or boolean or object | Training-data lineage is documented (Art. 10). |
organizational | data_sheet | string or object | A data sheet for the model's data (Art. 10). |
organizational | explainability_enabled | boolean | The agent's decisions can be explained (Art. 13). |
organizational | explanation_method | string | How they are explained. |
organizational | asset_inventory_ref | string | Reference to the asset inventory entry (NIST CSF ID.AM). |
organizational | system_asset_id | string | The system's asset ID. |
organizational | incident_response_plan_ref | string | Reference to the incident response plan. |
organizational | incident_report_ref | string | Reference to the incident report (NIST 800-53 IR-6). |
organizational | ato_status | string | FedRAMP Authority to Operate: "authorized", "in_process", "not_started". |
organizational | supply_chain_assessment_ref | string | Reference to the supply-chain risk assessment. |
organizational | cui_handling_procedures_ref | string | Reference to CUI handling procedures (CMMC). |
organizational | configuration_baseline_ref | string | Reference to the configuration baseline. |
organizational | change_management_ticket | string | Change ticket covering this change. |
organizational | monitoring_enabled | boolean | Continuous monitoring is enabled for the system. |
organizational | telemetry_endpoint | string | Where the system's telemetry goes. |
identity | authenticated_agent_id | string | The agent identity your identity provider authenticated. |
identity | account_status | string | Status of the agent's account, e.g. "active", "provisioned", "suspended". |
identity | last_account_review_days | number | Days since the agent's access was last reviewed. |
identity | assigned_permissions | array | Permissions assigned to the agent. |
identity | delegation_limit_usd | number | The agent's delegation limit, in USD. |
identity | recovery_authorization | boolean | The agent is authorized to run recovery actions. |
identity | clearance_status | string | Clearance for CUI, e.g. "cleared", "uncleared". |
identity | clearance_verified | boolean | The clearance was verified. |
security | privilege_escalation_alert | boolean | Your security tooling raised a privilege-escalation alert for this agent. |
security | prompt_injection_detected | boolean | A prompt injection was detected in this agent's inputs. |
security | active_security_incident | boolean | An active security incident affects the target or agent. |
security | siem_ref | string | Where this system's events go in your SIEM. |
Reserved. GaaS sets these itself; a value from your endpoint is dropped and flagged reserved_key_ignored:
environmental.context_confidence— GaaS computes context confidence itself.regulatory.ap2_mandate_present— Set by GaaS's AP2 mandate check.regulatory.ap2_mandate_valid— Set by GaaS's AP2 mandate check.regulatory.ap2_conditions_met— Set by GaaS's AP2 mandate check.
In the audit record
Every decision's audit record shows your endpoint as one source per category, customer_endpoint_<category>, in stage_2_enrichment.sources_queried, with its status and latency. A category that failed is also in sources_failed, and missing_context gives the reason, for example Source customer_endpoint_environmental returned status timed_out (timeout).
| Reason | Meaning |
|---|---|
timeout | No answer within the time limit |
http_error, redirect | A status other than 200 (redirects are not followed) |
invalid_response, contract_version_mismatch, too_large | The answer is not this contract's JSON, or is over 256 KB |
category_missing, invalid_fact:<key>, invalid_key, too_deep:<key>, too_many_keys | That category was absent or broke a rule above |
connect_error, ssrf_blocked | GaaS could not connect, or the address resolved to a private or internal network |
circuit_open | Five calls in a row failed, so GaaS pauses calls for 30 seconds |
concurrency_limited | Too many calls to your endpoint were already in flight |
secret_unavailable | GaaS could not open the saved secrets; the call was not made |
Security
- HTTPS on port 443 only, to a host name with a public TLS certificate. GaaS resolves the name before every call and refuses it if any address is private or internal, then connects to the address it checked.
- Your secrets are encrypted with AWS KMS before they are stored, bound to your organization, and opened only in memory to make the call. GaaS never shows them again, only their last four characters.
- Facts from your endpoint can let an action through that would otherwise be blocked; that is the point, so answer only what your systems know. Every decision records which categories your endpoint supplied.
- An organization admin can switch the endpoint off or remove it at any time, from the dashboard or the API.
Related
- Connectors — built-in integrations
- Shadow Mode — evaluate without enforcing
- Policies — what each policy checks
- Authentication — API keys and roles