Skip to Content
Getting startedQuickstart

Govern your first action

Use this scenario to check a test payment action. An amount of 100 or less should proceed; a larger amount should be stopped before the receipt is written. Inspect both the policy evidence and the receipt output to confirm those results.

Who can use this
Available to
DeveloperAdministrator
Not available to
Governance EngineerCompliance OfficerBusiness OwnerAuditor

Developers run the integration. Administrators provide Development application access. A Governance Engineer creates the test rule by default.

Install the approved packages

Open Tools and SDKs. It is an organization-wide item: Developers see it in the main navigation, and other roles find it under More tools. It is not part of an application workspace.

Choose Application SDKs, select your language, and add the adapter for your framework. Each adapter links one maintained governed-action runner. Use that runner for this scenario so its result contract, portal link, and cleanup steps match the released package version.

Select veriproof-sdk and veriproof-sdk-adapter-agent-framework, both version 1.0.0. The supported release uses Python 3.11 to 3.13 and agent-framework-core 1.18.0.

Tools and SDKs shows the install routes available to your account. If it offers the SDK bundle, use it: it downloads the packages through your portal sign-in and needs no package credential.

Otherwise, select Package registry. Create a package credential for your development computer, wait for it to be ready (this can take a few minutes), and run the commands shown in order. They keep the credential out of your shell history. Public dependencies still resolve from PyPI.

Keep the package token out of a saved index URL and out of source control.

Package access and application authentication are separate. Tools and SDK access explains package feeds, CI credentials, rotation, and revocation.

Configure application authentication

Open the application, select its Set up SDK tab, and create or copy the complete application key. The key identifies the application, so you don’t need a separate application ID. Store the key in your secret manager.

export VERIPROOF_API_KEY="your-complete-application-key"

Hosted VeriProof uses https://ingest.veriproof.app. VeriProof Private uses the ingest base URL supplied by your administrator in VERIPROOF_ENDPOINT.

A remote endpoint must use HTTPS. If you point VERIPROOF_ENDPOINT at a local http:// address, the SDK rejects it until you allow loopback HTTP as well. Python and .NET take this as a client option: Veriproof.from_env(allow_loopback_http=True) and AllowLoopbackHttp = true. TypeScript, Go, Java, and Rust read VERIPROOF_ALLOW_LOOPBACK_HTTP=true. See SDK configuration.

Create the test rule

Creating and activating the rule needs the Governance Engineer role by default. If you hold several roles, switch to Governance Engineer for these steps. See who can author and approve rules.

The rule reads the payment_amount fact that the sample sends with facts=. VeriProof places application facts at input.snapshot.facts.<name>. Run the sample below once with amount: 40 first, so VeriProof records the fact and offers it in the rule builder.

  1. Open the application’s Policy tab, select Create policy rule, then Create blank policy rule. Name it Quickstart payment limit.

  2. Under When the rule runs, choose Before action. Under When the rule matches, choose Block.

  3. In Review logic, set Apply “Block” when activity to Meets these conditions. Add the condition Payment Amount is greater than 100. Payment Amount appears under Sent by the application, not yet confirmed.

  4. In Confirm inputs, select Request Developer update. The Developer confirms the field from the application’s Policy tab, under Application data. If you hold the Developer role yourself, switch to it and confirm the field there.

  5. In Test, add two cases with this application data, changing only the amount:

    { "snapshot": { "facts": { "payment_amount": 140 } } }

    Expect Block for 140 and Continue for 40.

  6. Save the tested version, activate it in Shadow, run the sample with both amounts, and compare the proposed results. Then select Enforce. Development deployment does not use the Production approval path.

Advanced Rego shows the policy the builder generates, if you want to review it.

Run the governed action

Keep the payment write inside the operation that VeriProof evaluates before execution. Writing the receipt elsewhere would bypass that check, even if the session still records a policy decision.

Pass the receipt function to govern. Supply the payment amount as an application fact so the rule can evaluate it without reading prompt text:

import asyncio from veriproof_sdk import Veriproof async def write_test_receipt(context): context.throw_if_stopped() return {"receipt_id": f"rcpt-{context.input['reference']}"} async def main(): payment = {"reference": "QS-1", "amount": 40} async with Veriproof.from_env() as vp: result = await vp.govern( "payment.create", payment, write_test_receipt, facts={"payment_amount": payment["amount"]}, ) print(result.status, result.session_id, result.evidence_reference) if result.completed: print("receipt:", result.value) else: print("no receipt:", result.reason_code, result.message) asyncio.run(main())

govern is async, so run it from async code. async with closes the client and sends buffered evidence when the block ends. The core SDK checks the input before it calls write_test_receipt, so a stopped run never reaches the receipt write.

Run the sample twice: first with amount 40, then with amount 140.

The first run returns status completed and a receipt. The second returns blocked, which the portal shows as Stopped by policy, with no value and no receipt.

Record the identifiers from the result

Every core SDK returns the same result shape. There is no top-level decision ID. The decision ID lives on the optional decision object, and evidenceReference is a separate opaque string you can record but should not parse.

LanguageSessionDecision IDEvidence reference
Pythonresult.session_idresult.decision.decision_id if result.decision else Noneresult.evidence_reference
TypeScriptresult.sessionIdresult.decision?.decisionIdresult.evidenceReference
.NETresult.SessionIdresult.Decision?.DecisionIdresult.EvidenceReference
Javaresult.sessionId()result.decision() == null ? null : result.decision().decisionId()result.evidenceReference()
Goresult.SessionIDresult.Decision.DecisionID after checking result.Decision != nilresult.EvidenceReference
Rustresult.session_idresult.decision.as_ref().map(|d| d.decision_id.clone())result.evidence_reference

decision is absent when no rule decided the outcome, such as a transport failure, so check it before reading the decision ID. In Python, TypeScript and .NET the decision ID itself can also be empty; in Go and Rust it is always set when decision is present. Every decision also carries decisionCorrelationId. On a review_required result the same identifiers are on the review checkpoint.

The evidence reference is an opaque string. Hosted Server Ingest can return policy-evaluation-event:<uuid>; an Edge Gateway receipt can return edge:<id>. Other results can return decision:<id>, a correlation ID, or unavailable. Record the value as returned. Do not parse it to make a policy decision.

Prove the result

Confirm the allowed run created one test receipt. Confirm the stopped run created none.

Open the session and decision from the identifiers you recorded:

/applications/{applicationId}/sessions/{sessionId}?tab=decision&decisionId={decisionId}

For decisionId, use the decision correlation ID. If a hosted result includes a policy-evaluation-event: reference, the UUID after that prefix is the decision event ID shown under Evidence details.

The highlighted decision card under Enforcement events during this session shows:

  • the outcome: Allowed for amount 40, and Stopped by policy for amount 140;
  • the rule name and its version;
  • which check ran, such as Before tool call or Input policy check;
  • the time of the decision; and
  • Why, the reason the rule recorded.

Select Evidence details on that card for the event ID and prompt hash.

The card reports what the rule decided, not how the rule is deployed. To confirm the rule was enforcing rather than observing, use Control coverage in the next step.

Confirm the operation is enforced

Open the application’s Control coverage tab and confirm payment.create appears under Enforce. If it appears under Observe, VeriProof recorded the action but nothing stopped it, so the result above was not enforcement.

Clean up

Delete the synthetic receipts, remove the test rule, and revoke any temporary application key. Remove local sample secrets and generated package credentials from the test environment.

Diagnose a failed run

  • For a 401 or 403, check the returned error, key status, application permissions, and endpoint. The status alone does not identify the cause.
  • A missing decision usually means the protected action ran outside the governed path or no inline rule matched.
  • Observe or Not supported in Control coverage means the SDK path does not control that operation.
  • An unsupported stream must remain buffered or unreleased until a supported boundary decides it.

Use Troubleshoot the SDK for detailed checks.

Last updated on