import z from"@contractspec/lib.ui-link";import{ChevronRight as A}from"lucide-react";import{jsx as q,jsxs as y}from"react/jsx-runtime";function E(){return y("div",{className:"space-y-8",children:[y("div",{className:"space-y-4",children:[q("h1",{className:"font-bold text-4xl",children:"Policy"}),y("p",{className:"text-muted-foreground",children:["A ",q("strong",{children:"PolicySpec"})," defines who can do what, when, and under what conditions. ContractSpec uses attribute-based access control (ABAC) to enforce policies across your entire application—from API endpoints to UI components."]})]}),y("div",{className:"space-y-4",children:[q("h2",{className:"font-bold text-2xl",children:"Why policies matter"}),q("p",{className:"text-muted-foreground",children:"Traditional access control relies on roles (RBAC), which can become unwieldy as applications grow. ABAC is more flexible—it evaluates policies based on attributes of the user, resource, action, and context."}),y("p",{className:"text-muted-foreground",children:["ContractSpec's policy engine ensures that access control is consistent across all surfaces. You don't have to remember to add authorization checks in every API endpoint or UI component—the"," ",q(z,{href:"/docs/safety/pdp",className:"text-violet-400 hover:text-violet-300",children:"Policy Decision Point"})," ","enforces policies automatically."]})]}),y("div",{className:"space-y-4",children:[q("h2",{className:"font-bold text-2xl",children:"Policy structure"}),q("p",{className:"text-muted-foreground",children:"A PolicySpec contains one or more rules. Each rule has:"}),y("ul",{className:"list-inside list-disc space-y-2 text-muted-foreground",children:[y("li",{children:[q("strong",{children:"Effect"})," – PERMIT, DENY, or REDACT"]}),y("li",{children:[q("strong",{children:"Condition"})," – A boolean expression that determines when the rule applies"]}),y("li",{children:[q("strong",{children:"Scope"})," – Which resources, actions, or fields the rule applies to"]}),y("li",{children:[q("strong",{children:"Priority"})," – Rules are evaluated in priority order; the first matching rule wins"]})]})]}),y("div",{className:"space-y-4",children:[q("h2",{className:"font-bold text-2xl",children:"Example PolicySpec"}),q("p",{className:"text-muted-foreground",children:"Here's a policy that controls access to customer data in TypeScript:"}),q("div",{className:"overflow-x-auto rounded-lg border border-border bg-background/50 p-4 font-mono text-muted-foreground text-sm",children:q("pre",{children:`import { definePolicy } from '@contractspec/lib.contracts-spec';

export const CustomerDataAccess = definePolicy({
  meta: {
    key: 'customer.data.access',
    version: '1.0.0',
  },
  rules: [
    {
      id: 'admin-full-access',
      priority: 100,
      effect: 'PERMIT',
      condition: (ctx) => ctx.user.role === 'admin',
      scope: {
        resources: ['customer'],
        actions: ['read', 'write', 'delete'],
      },
    },
    {
      id: 'sales-read-assigned',
      priority: 200,
      effect: 'PERMIT',
      condition: (ctx) => 
        ctx.user.role === 'sales' && 
        ctx.resource.assignedTo === ctx.user.id,
      scope: {
        resources: ['customer'],
        actions: ['read', 'write'],
      },
    },
    {
      id: 'support-read-redacted',
      priority: 300,
      effect: 'REDACT',
      condition: (ctx) => ctx.user.role === 'support',
      scope: {
        resources: ['customer'],
        actions: ['read'],
      },
      redactFields: ['creditCard', 'ssn', 'bankAccount'],
    },
  ],
});`})})]}),y("div",{className:"space-y-4",children:[q("h2",{className:"font-bold text-2xl",children:"Attributes"}),q("p",{className:"text-muted-foreground",children:"Policy conditions can reference attributes from four categories:"}),y("div",{className:"space-y-3",children:[y("div",{children:[q("h3",{className:"font-semibold text-lg",children:"User attributes"}),y("p",{className:"text-muted-foreground",children:[q("code",{className:"rounded bg-background/50 px-2 py-1",children:"user.id"}),","," ",q("code",{className:"rounded bg-background/50 px-2 py-1",children:"user.role"}),","," ",q("code",{className:"rounded bg-background/50 px-2 py-1",children:"user.groups"}),","," ",q("code",{className:"rounded bg-background/50 px-2 py-1",children:"user.department"}),", custom attributes"]})]}),y("div",{children:[q("h3",{className:"font-semibold text-lg",children:"Resource attributes"}),y("p",{className:"text-muted-foreground",children:[q("code",{className:"rounded bg-background/50 px-2 py-1",children:"resource.type"}),","," ",q("code",{className:"rounded bg-background/50 px-2 py-1",children:"resource.owner"}),","," ",q("code",{className:"rounded bg-background/50 px-2 py-1",children:"resource.sensitivity"}),", custom attributes"]})]}),y("div",{children:[q("h3",{className:"font-semibold text-lg",children:"Action attributes"}),y("p",{className:"text-muted-foreground",children:[q("code",{className:"rounded bg-background/50 px-2 py-1",children:"action"})," ","(read, write, delete, execute, export, etc.)"]})]}),y("div",{children:[q("h3",{className:"font-semibold text-lg",children:"Context attributes"}),y("p",{className:"text-muted-foreground",children:[q("code",{className:"rounded bg-background/50 px-2 py-1",children:"time.hour"}),","," ",q("code",{className:"rounded bg-background/50 px-2 py-1",children:"time.dayOfWeek"}),","," ",q("code",{className:"rounded bg-background/50 px-2 py-1",children:"request.ipAddress"}),","," ",q("code",{className:"rounded bg-background/50 px-2 py-1",children:"request.userAgent"})]})]})]})]}),y("div",{className:"space-y-4",children:[q("h2",{className:"font-bold text-2xl",children:"Data classification"}),y("p",{className:"text-muted-foreground",children:["You can tag fields with sensitivity levels in your"," ",q(z,{href:"/docs/specs/capabilities",className:"text-violet-400 hover:text-violet-300",children:"CapabilitySpecs"})," ","and"," ",q(z,{href:"/docs/specs/dataviews",className:"text-violet-400 hover:text-violet-300",children:"DataViewSpecs"}),":"]}),q("div",{className:"overflow-x-auto rounded-lg border border-border bg-background/50 p-4 font-mono text-muted-foreground text-sm",children:q("pre",{children:`fields:
  - name: email
    type: string
    sensitivity: PII
  - name: creditCard
    type: string
    sensitivity: PII
    encrypted: true
  - name: diagnosis
    type: string
    sensitivity: PHI
  - name: salary
    type: number
    sensitivity: confidential`})}),q("p",{className:"text-muted-foreground",children:'Policies can then reference these tags to enforce blanket rules like "support staff cannot see PII" or "PHI can only be accessed from approved IP addresses."'})]}),y("div",{className:"space-y-4",children:[q("h2",{className:"font-bold text-2xl",children:"Testing policies"}),q("p",{className:"text-muted-foreground",children:"ContractSpec provides tools for testing policies before deployment:"}),y("ul",{className:"list-inside list-disc space-y-2 text-muted-foreground",children:[y("li",{children:[q("strong",{children:"Policy simulator"})," – Test how policies evaluate for different users and scenarios"]}),y("li",{children:[q("strong",{children:"Coverage analysis"})," – Identify resources or actions that aren't covered by any policy"]}),y("li",{children:[q("strong",{children:"Conflict detection"})," – Find rules that might conflict or produce unexpected results"]}),y("li",{children:[q("strong",{children:"Audit mode"})," – Run policies in audit-only mode to see what would be blocked without actually blocking it"]})]})]}),y("div",{className:"space-y-4",children:[q("h2",{className:"font-bold text-2xl",children:"Best practices"}),y("ul",{className:"list-inside list-disc space-y-2 text-muted-foreground",children:[q("li",{children:"Start with a deny-by-default policy—explicitly permit what should be allowed."}),q("li",{children:"Use clear, descriptive rule IDs that explain what the rule does."}),q("li",{children:"Set priorities carefully to ensure rules are evaluated in the right order."}),q("li",{children:"Test policies thoroughly with realistic user scenarios before deploying."}),y("li",{children:["Monitor policy decisions in production using"," ",q(z,{href:"/docs/safety/auditing",className:"text-violet-400 hover:text-violet-300",children:"audit logs"}),"."]}),q("li",{children:"Review and update policies regularly as your application and requirements evolve."})]})]}),y("div",{className:"flex items-center gap-4 pt-4",children:[q(z,{href:"/docs/specs/workflows",className:"btn-ghost",children:"Previous: Workflows"}),y(z,{href:"/docs/specs/overlays",className:"btn-primary",children:["Next: Overlays ",q(A,{size:16})]})]})]})}export{E as SpecsPolicyPage};
