Skip to main content

Policy Engine

ID Wispera includes a Cedar-inspired policy engine for declarative credential governance.

Overview

Policies define rules that control:
  • Who can access which credentials
  • Under what conditions access is allowed
  • What approval workflows are required
  • How long credentials can be valid

Policy Structure

interface PolicyRule {
  id: string;           // Unique identifier
  name: string;         // Human-readable name
  description: string;  // What this rule enforces
  condition: {          // When the rule applies
    visaTypes?: VisaType[];
    platforms?: Platform[];
    maxDelegationDepth?: number;
    requireHumanOwner?: boolean;
    maxValidityDays?: number;
  };
  effect: 'allow' | 'deny' | 'require-approval';
  priority?: number;    // Higher = evaluated first
  enabled?: boolean;
}

Default Rules

ID Wispera includes sensible defaults out of the box.
These default rules enforce baseline security hygiene. You can override any of them by creating a custom rule with the same id.
const DEFAULT_POLICY_RULES = [
  {
    id: 'require-human-owner',
    name: 'Require Human Owner',
    description: 'All passports must have a human owner',
    condition: { requireHumanOwner: true },
    effect: 'deny',
    priority: 100,
  },
  {
    id: 'max-validity-90-days',
    name: 'Maximum Validity Period',
    description: 'Credentials should not be valid for more than 90 days',
    condition: { maxValidityDays: 90 },
    effect: 'deny',
    priority: 90,
  },
  {
    id: 'max-delegation-depth-3',
    name: 'Maximum Delegation Depth',
    description: 'Credentials should not be delegated more than 3 levels',
    condition: { maxDelegationDepth: 3 },
    effect: 'deny',
    priority: 80,
  },
  {
    id: 'privilege-visa-requires-approval',
    name: 'Privileged Access Requires Approval',
    condition: { visaTypes: ['privilege'] },
    effect: 'require-approval',
    priority: 70,
  },
];

Using the Policy Engine

Evaluate a Policy

import { evaluatePolicy, DEFAULT_POLICY_RULES } from '@id-wispera/core';

const decision = evaluatePolicy(passport, 'access', DEFAULT_POLICY_RULES);

if (!decision.allowed) {
  console.log('Access denied:', decision.reason);
}

Validate a Passport

import { validatePassport, DEFAULT_POLICY_RULES } from '@id-wispera/core';

const violations = validatePassport(passport, DEFAULT_POLICY_RULES);

for (const v of violations) {
  console.log(`${v.severity}: ${v.violation}`);
}

Creating Custom Rules

Using createPolicyRule

import { createPolicyRule } from '@id-wispera/core';

const rule = createPolicyRule({
  name: 'Production Credentials Short Expiry',
  description: 'Production credentials must expire within 30 days',
  condition: {
    tags: ['production'],
    maxValidityDays: 30,
  },
  effect: 'deny',
  priority: 95,
});

Using the Fluent Builder

import { policy } from '@id-wispera/core';

const rule = policy('compliance-no-delegation')
  .name('No Delegation for Compliance')
  .description('Compliance credentials cannot be delegated')
  .forVisaTypes('compliance')
  .maxDelegationDepth(0)
  .deny()
  .priority(100)
  .build();
The fluent builder is available in the TypeScript SDK. For Python and Go, use the createPolicyRule / create_policy_rule / CreateRule functions shown above.

Policy Conditions

Visa Type Filter

Apply a rule only to specific visa types:
condition: { visaTypes: ['privilege', 'compliance'] }

Platform Filter

Apply a rule only to specific platforms:
condition: { platforms: ['openai', 'anthropic'] }

Scope Filter

Apply a rule when specific scopes are present:
condition: { scopes: ['admin', 'delete'] }

Delegation Depth

Limit how many times a credential can be delegated:
condition: { maxDelegationDepth: 2 }

Validity Period

Limit how long a credential can be valid:
condition: { maxValidityDays: 30 }

Human Owner Requirement

Require a human owner to be set:
condition: { requireHumanOwner: true }

Tag Filter

Apply a rule to passports with specific tags:
condition: { tags: ['production', 'sensitive'] }

Custom Condition

For complex logic that cannot be expressed declaratively:
Custom condition functions run in-process and are not serializable. Use them only in programmatic integrations, not in exported policy files.
condition: {
  custom: (passport) => {
    return passport.scope.length > 10;
  }
}

Policy Effects

EffectBehavior
allowAccess is granted
denyAccess is blocked
require-approvalAccess needs human approval before it is granted

Merging Policy Sets

Combine multiple rule sets into a single evaluation list:
import { mergePolicyRules, DEFAULT_POLICY_RULES } from '@id-wispera/core';

const customRules = [/* your rules */];
const allRules = mergePolicyRules(DEFAULT_POLICY_RULES, customRules);
Later rules with the same id override earlier ones. This lets you selectively replace default rules without removing the rest.

Best Practices

  1. Start with defaults and add custom rules as needed.
  2. Use high priorities for critical security rules.
  3. Test policies before deploying to production.
  4. Document rules with clear descriptions.
  5. Review periodically to ensure rules are still relevant.
  6. Log policy decisions for audit purposes.

Next Steps