Policy pack setup
This page walks you through setting up your first custom policy pack using the Arbitex API. It covers creating a pack, adding rules, configuring the org policy chain, and testing your configuration with the simulate endpoint.
A note on scope: the admin UI for policy management is not yet available. All configuration shown here uses the API directly. The same operations will be available in the UI when it ships — the data model is identical.
For a conceptual explanation of how packs, rules, chains, and evaluation work, read Policy Engine overview first. This page focuses on the mechanics of creating and configuring those objects.
Creating a custom policy pack
Section titled “Creating a custom policy pack”A custom policy pack is a named container for your enforcement rules. You create it once, then add rules to it. The pack is not active until you add it to your org policy chain.
POST https://api.arbitex.ai/api/admin/orgs/{org_id}/policy/packsAuthorization: Bearer arb_live_your-api-key-hereContent-Type: application/json
{ "name": "Trading Desk Rules", "description": "Enforcement rules for the trading desk group.", "pack_type": "custom"}{ "pack_id": "pack_01HZ_TRADING_DESK", "name": "Trading Desk Rules", "description": "Enforcement rules for the trading desk group.", "pack_type": "custom", "created_at": "2026-03-08T14:00:00Z", "rule_count": 0}Save the pack_id — you will use it when adding rules and when configuring the chain.
Adding a rule: block OpenAI for the no-openai group
Section titled “Adding a rule: block OpenAI for the no-openai group”This rule blocks all requests to OpenAI for users in the no-openai group. It uses two conditions that both must match: the user must be in the group, and the request must be destined for the OpenAI provider.
POST https://api.arbitex.ai/api/admin/orgs/{org_id}/policy/packs/{pack_id}/rulesAuthorization: Bearer arb_live_your-api-key-hereContent-Type: application/json
{ "name": "Block OpenAI for no-openai group", "sequence": 10, "applies_to": "input", "conditions": { "user_groups": ["no-openai"], "providers": ["openai"] }, "action": "BLOCK", "message": "OpenAI access is not permitted for your group. Use the approved provider list instead."}{ "rule_id": "rule_01HZ_BLOCK_OPENAI", "pack_id": "pack_01HZ_TRADING_DESK", "name": "Block OpenAI for no-openai group", "sequence": 10, "applies_to": "input", "conditions": { "user_groups": ["no-openai"], "providers": ["openai"] }, "action": "BLOCK", "message": "OpenAI access is not permitted for your group. Use the approved provider list instead.", "created_at": "2026-03-08T14:01:00Z"}The sequence field controls evaluation order within the pack. Lower numbers evaluate first. Leave gaps between sequence numbers (10, 20, 30) so you can insert rules later without renumbering.
The message field is optional. When set, it appears in the 403 policy_block error response body that the caller receives. Write messages that tell the user what to do rather than just what was blocked — they may be shown in UI surfaces.
Adding a rule: redact credit cards globally
Section titled “Adding a rule: redact credit cards globally”This rule applies to all users and all providers. It has no group condition — any request containing a credit card number gets the card number redacted before the prompt is forwarded. Unlike BLOCK, the REDACT action is non-terminal: other rules continue to evaluate after redaction runs.
POST https://api.arbitex.ai/api/admin/orgs/{org_id}/policy/packs/{pack_id}/rulesAuthorization: Bearer arb_live_your-api-key-hereContent-Type: application/json
{ "name": "Redact credit cards globally", "sequence": 20, "applies_to": "both", "conditions": { "entity_types": ["credit_card"], "entity_confidence_min": 0.85 }, "action": "REDACT", "redact_replacement": "[CC-REMOVED]"}{ "rule_id": "rule_01HZ_REDACT_CC", "pack_id": "pack_01HZ_TRADING_DESK", "name": "Redact credit cards globally", "sequence": 20, "applies_to": "both", "conditions": { "entity_types": ["credit_card"], "entity_confidence_min": 0.85 }, "action": "REDACT", "redact_replacement": "[CC-REMOVED]", "created_at": "2026-03-08T14:02:00Z"}Setting applies_to: "both" means this rule runs on both the user’s input prompt and the model’s output response. If the model echoes a credit card number in its reply, the rule fires on output as well.
Setting entity_confidence_min: 0.85 means only detections with a DLP confidence score of 0.85 or above trigger the rule. This reduces false positives from the NER tier on strings that look like card numbers but fail contextual validation.
Configuring the org policy chain
Section titled “Configuring the org policy chain”Once your pack is ready, add it to your organization’s policy chain. The chain controls which packs are active and in what evaluation order. Sequence values determine precedence: lower sequences are evaluated first.
PUT https://api.arbitex.ai/api/admin/orgs/{org_id}/policy/chainAuthorization: Bearer arb_live_your-api-key-hereContent-Type: application/json
{ "combining_algorithm": "first_applicable", "packs": [ { "pack_id": "pack_01HZ_TRADING_DESK", "sequence": 10 } ]}{ "org_id": "org_acme", "combining_algorithm": "first_applicable", "packs": [ { "pack_id": "pack_01HZ_TRADING_DESK", "sequence": 10, "pack_name": "Trading Desk Rules", "pack_type": "custom", "rule_count": 2 } ], "updated_at": "2026-03-08T14:05:00Z"}The PUT /policy/chain endpoint replaces the full chain. If you have existing packs in the chain, include them all in the request body — omitting a pack removes it from the chain.
combining_algorithm: "first_applicable" is the recommended setting for most organizations. The first terminal match wins. See Policy Engine overview — Combining algorithm for when to use deny_overrides instead.
To add a compliance bundle alongside your custom pack, include its pack_id in the same packs array. Compliance bundle pack IDs are retrievable from GET /api/admin/orgs/{org_id}/policy/bundles.
Testing with the simulate endpoint
Section titled “Testing with the simulate endpoint”Before your policy changes affect live traffic, use the simulate endpoint to verify rule behavior. The simulate endpoint runs a synthetic request through the full policy evaluation pipeline without forwarding the request to any model provider.
Simulate a request that should be blocked
Section titled “Simulate a request that should be blocked”POST https://api.arbitex.ai/api/admin/orgs/{org_id}/policy/simulateAuthorization: Bearer arb_live_your-api-key-hereContent-Type: application/json
{ "user_id": "usr_test_trader", "user_groups": ["no-openai"], "provider": "openai", "model": "gpt-4o", "prompt": "Explain the mechanics of a credit default swap."}{ "outcome": "BLOCK", "matched_pack_id": "pack_01HZ_TRADING_DESK", "matched_rule_id": "rule_01HZ_BLOCK_OPENAI", "matched_rule_name": "Block OpenAI for no-openai group", "matched_sequence": 10, "match_reason": "user_groups matched ['no-openai']; providers matched ['openai']", "action_taken": "BLOCK", "message": "OpenAI access is not permitted for your group. Use the approved provider list instead.", "dlp_findings": []}The response shows exactly which pack and rule matched, at which sequence position, and why. This is the same information that appears in a real audit log entry.
Simulate a request that should be redacted
Section titled “Simulate a request that should be redacted”POST https://api.arbitex.ai/api/admin/orgs/{org_id}/policy/simulateAuthorization: Bearer arb_live_your-api-key-hereContent-Type: application/json
{ "user_id": "usr_test_analyst", "user_groups": ["finance"], "provider": "anthropic", "model": "claude-sonnet-4-20250514", "prompt": "The cardholder's Visa number is 4111111111111111 — is this valid?"}{ "outcome": "REDACT", "matched_pack_id": "pack_01HZ_TRADING_DESK", "matched_rule_id": "rule_01HZ_REDACT_CC", "matched_rule_name": "Redact credit cards globally", "matched_sequence": 20, "match_reason": "entity_types detected: credit_card (confidence 0.98)", "action_taken": "REDACT", "redacted_prompt": "The cardholder's Visa number is [CC-REMOVED] — is this valid?", "dlp_findings": [ { "entity_type": "credit_card", "tier": 1, "confidence": 0.98, "offset": 34, "length": 16 } ]}The redacted_prompt field in the simulate response shows you exactly what would be forwarded to the upstream provider after redaction. Use this to verify that your entity_confidence_min threshold is set appropriately and that the replacement string looks correct in context.
Simulate a request that should pass through
Section titled “Simulate a request that should pass through”POST https://api.arbitex.ai/api/admin/orgs/{org_id}/policy/simulateAuthorization: Bearer arb_live_your-api-key-hereContent-Type: application/json
{ "user_id": "usr_test_analyst", "user_groups": ["finance"], "provider": "anthropic", "model": "claude-sonnet-4-20250514", "prompt": "Summarize the key provisions of SOX Section 404."}{ "outcome": "ALLOW", "matched_pack_id": null, "matched_rule_id": null, "match_reason": "No rule matched. Default action: ALLOW.", "action_taken": "ALLOW", "dlp_findings": []}A null match result means no rule in the chain matched this request. The default terminal action is ALLOW. If your posture requires that anything not explicitly permitted is denied, add a catch-all BLOCK rule with no conditions at a high sequence number (for example, sequence=999) as described in Policy Engine overview — Default terminal action.
Updating and removing rules
Section titled “Updating and removing rules”Update a rule
Section titled “Update a rule”PATCH a rule to change specific fields without replacing the whole object:
PATCH https://api.arbitex.ai/api/admin/orgs/{org_id}/policy/packs/{pack_id}/rules/{rule_id}Authorization: Bearer arb_live_your-api-key-hereContent-Type: application/json
{ "entity_confidence_min": 0.90, "message": "Updated block message."}Only the fields you include are updated. Fields you omit retain their current values.
Remove a rule from a pack
Section titled “Remove a rule from a pack”DELETE https://api.arbitex.ai/api/admin/orgs/{org_id}/policy/packs/{pack_id}/rules/{rule_id}Authorization: Bearer arb_live_your-api-key-hereReturns 204 No Content on success. The deletion takes effect immediately for new requests. In-flight requests that are already mid-evaluation are not affected.
See also
Section titled “See also”- Policy Engine overview — evaluation flow, combining algorithms, and action semantics
- Policy Rule Reference — complete list of condition fields and action types with examples
- Compliance Bundles — adding pre-configured bundle packs to your chain alongside custom packs
- Entra ID SCIM provisioning — setting up the group sync that powers
user_groupsconditions