Getting Started with Policy Information Points (PIPs)

What is a PIP?

A Policy Information Point (PIP) is a data source that provides real-time context and attributes for your access control policies. Think of it as connecting your authorization system to the sources of truth in your organization.

Why Connect Data Sources?

Without PIPs, your policies are limited to information in the request itself. With PIPs, your policies can access:

  • User Information from your identity provider (roles, department, manager, clearance level)
  • Resource Metadata from databases (owner, sensitivity, environment, status)
  • HR Context from your HR system (employment status, start date, certifications)
  • Business Context from CRM/ERP systems (customer tier, account status)
  • Real-Time Context for dynamic, intelligent authorization decisions

Where PIPs Sit in the System

Data sources (PIPs) are configured in the Control Plane. The Policy Bridge distributes that data to all bouncers so policies can use it at evaluation time.

Click to enlarge

Real-World Example

Without PIP:

User requests access to "Production Database"
Policy checks: Does user have "database-admin" role?
Decision: Simple yes/no based on static role

With PIP:

User requests access to "Production Database"
Policy checks:
  - User's department (from Okta)
  - User's employment status (from Workday)
  - Resource owner (from PostgreSQL metadata)
  - Time of day and user's location
  - User's clearance level and certifications
Decision: Smart, context-aware authorization

Quick Start: Connect Your First Data Source

The flow from adding a data source to using it in policies:

Click to enlarge

Step 1: Access PIP Management

You can access PIP Management in two places:

  1. During Onboarding: In the Getting Started Wizard → "Connect Data Sources" step
  2. Anytime Later: Settings → Data Sources

Step 2: Choose Your Data Source

Click "Add Data Source" and select from 13 categories:

Identity & HR

  • Identity Provider (Okta, Azure AD, Auth0, LDAP)
  • HR System (Workday, BambooHR, ADP)

Enterprise Systems

  • CRM (Salesforce, HubSpot, Dynamics)
  • ERP (SAP, Oracle, NetSuite)
  • Ticketing (ServiceNow, Jira, Zendesk)

Data & Storage

  • Database (PostgreSQL, MySQL, MongoDB)
  • Document Storage (SharePoint, Google Drive, S3)
  • Data Warehouse (Snowflake, BigQuery, Redshift)

Technical

  • OpenAPI Specification
  • Custom API
  • Configuration Management Database (CMDB)

Step 3: Configure Connection

Let's walk through connecting Okta as an example:

3.1 Enter Basic Information

  • Name: "Production Okta" (friendly name for your team)
  • Provider: Select "Okta"

3.2 Choose Authentication Method

  • OAuth 2.0 (Recommended) - Most secure, tokens auto-refresh
  • API Key - Simpler setup, good for read-only access
  • Username/Password - For legacy systems only

3.3 Configure OAuth (if selected)

  • Okta Domain: your-company.okta.com
  • Client ID: From your Okta admin console
  • Client Secret: From your Okta admin console
  • Scopes: openid profile email groups (default is good!)

Where to get OAuth credentials: In Okta, go to Applications → Create App Integration → API Services or Web App

3.4 Test Connection

Click "Test Connection" - this is where the magic happens!

The system will:

  1. Connect to your Okta instance
  2. Discover all available user fields
  3. Show you REAL metadata from your Okta

Step 4: Understanding the Metadata

After successful connection test, you'll see two sections:

Available Metadata Fields (LEFT SIDE)

These are REAL fields from your data source:

For Okta, you'll see actual fields like:

  • id - User ID
  • email - Email address
  • firstName, lastName - Name fields
  • status - User status (ACTIVE, INACTIVE, etc.)
  • profile.department - User's department
  • profile.title - Job title
  • groups - Group memberships
  • lastLogin - Last login timestamp
  • Plus any custom fields you've added to Okta!

This is NOT sample data - it's the actual schema from your connected system!

Authorization Attributes (RIGHT SIDE)

These are standard attribute names used in your policies:

  • user.id - Unique user identifier
  • user.email - User email address
  • user.department - Department name
  • user.roles - Role assignments
  • user.groups - Group memberships
  • user.mfa_enabled - MFA status
  • user.clearance_level - Security clearance

Step 5: Map the Attributes

Mapping connects real fields to policy attributes:

Policy Attribute (What policies use)Okta Field (Real field name)
user.emailemail
user.departmentprofile.department
user.rolesgroups
user.managerprofile.manager

Why map?

  • Policies use standard names like user.department
  • Different providers have different field names (Okta: profile.department, Azure AD: department)
  • Mapping lets you switch providers without rewriting policies!

Step 6: Configure Sync Settings

Sync Frequency: How often to refresh data from the source

  • Real-time (Webhooks): Instant updates when data changes (best for critical data)
  • Every 5 minutes: Near real-time
  • Hourly: Standard refresh rate (good for most use cases)
  • Daily: For relatively static data
  • Weekly: For reference data

Recommendation: Start with "Hourly" - you can adjust later!

Step 7: Save and You're Done!

Click "Save Information Source"

Your data source is now connected! Within minutes:

  1. Control Core fetches user data from Okta
  2. Applies your attribute mappings
  3. Makes the data available to ALL your policies
  4. Distributes to ALL your Bouncers (PEPs) automatically

Common Use Cases

Use Case 1: Department-Based Access

Scenario: Only Engineering team can access development APIs

Setup:

  1. Connect Okta (for user department)
  2. Map user.departmentprofile.department

Policy (automatically gets department from Okta):

Allow access if:
  - User's department = "Engineering"
  - Resource environment = "development"

Use Case 2: Resource Ownership

Scenario: Users can only access resources they own

Setup:

  1. Connect Okta (for user ID)
  2. Connect PostgreSQL (for resource metadata)
  3. Map user.idid
  4. Map resource.owner_idowner_id (from database)

Policy (gets data from both sources):

Allow access if:
  - Resource owner = Current user ID
  OR
  - User has "admin" role

Use Case 3: Compliance & Clearance

Scenario: Only certified employees can access PII data

Setup:

  1. Connect Workday (for employee certifications)
  2. Connect PostgreSQL (for data classification)
  3. Map user.certificationscertifications
  4. Map resource.classificationdata_classification

Policy:

Allow access if:
  - User has "PII-Handler" certification
  - User's background check = "Passed"
  - Resource classification = "PII"

Real-world PIP scenario library

These eight scenarios show how Policy Information Points (PIPs) turn static request attributes into controls that match Canadian and regulated enterprise workloads. Each scenario lists business context, required PIPs, attribute mapping, a Rego snippet, and what happens if you skip the PIP.

Terminology: In Control Core the rules you author are controls. Under the hood each control is a Rego policy evaluated by OPA. PIP data arrives via the Policy Bridge (OPAL) as data.pip.* — never as a per-request round-trip to Okta or Workday.

1. Canadian bank wire certification (Workday + Postgres + Okta)

Business context: A Schedule I bank must prove that wire initiators hold current AML certification and an active employment record before high-value transfers leave the payment rail (FINTRAC / OSFI B-13).

PIPs required: Workday (HR), PostgreSQL (certification ledger), Okta (identity groups).

Control attributePIP source field
user.employment_statusWorkday Worker_Status
user.aml_cert_expiryPostgres certifications.aml_expiry
user.groupsOkta groups
package controlcore.wire_cert

import rego.v1

default allow := false

allow if {
  data.pip.workday.users[input.user.id].employment_status == "Active"
  time.now_ns() < time.parse_rfc3339_ns(data.pip.postgres.certifications[input.user.id].aml_expiry)
  "wire-operators" in data.pip.okta.users[input.user.id].groups
}

Without PIP: Controls can only inspect JWT roles. Terminated or uncertified staff with a leftover group claim still initiate wires; auditors see no employment or certification evidence.

Business context: An Ontario hospital EMR must block chart access unless the clinician has an active encounter relationship and the patient has not withdrawn consent (PIPEDA 4.3 / PHIPA).

PIPs required: PostgreSQL (encounter + consent tables), Azure AD or Okta (clinician identity).

Control attributePIP source field
user.npiIdP employeeId
resource.patient_idRequest path / body (traffic)
patient.consent_statusPostgres consents.status
encounter.activePostgres encounters.active
package controlcore.emr_consent

import rego.v1

default allow := false

allow if {
  data.pip.postgres.encounters[input.resource.patient_id][input.user.id].active == true
  data.pip.postgres.consents[input.resource.patient_id].status == "granted"
}

Without PIP: Encounter and consent are invisible. Controls either over-allow (privacy breach) or over-deny (care disruption) with no audit trail tied to consent state.

3. Financial AI prompt clearance (OSFI / NIST AI RMF)

Business context: A capital-markets desk routes analyst prompts to an LLM gateway. Prompts that reference restricted issuer data require clearance ≥ Secret and an AI-use attestation (OSFI B-13 model risk / NIST AI RMF Govern + Map).

PIPs required: Okta (clearance custom attribute), Workday (AI attestation training), optional Postgres (model risk register).

Control attributePIP source field
user.clearance_levelOkta profile.clearance
user.ai_attestationWorkday Training_Completion
resource.model_risk_tierPostgres model_register.tier
package controlcore.ai_prompt_clearance

import rego.v1

default allow := false

allow if {
  data.pip.okta.users[input.user.id].clearance_level in {"secret", "top_secret"}
  data.pip.workday.users[input.user.id].ai_attestation == true
  input.agent_context.prompt_classification != "restricted_issuer"
}

Without PIP: Prompt controls see only path/model name. Restricted issuer content slips through; compliance packs mark related AI controls CANNOT_ASSESS.

4. HR Workday termination — instant revoke

Business context: When HR marks a worker terminated in Workday, every Bouncer must deny privileged API access within the webhook/sync window — not at next nightly IdP sync.

PIPs required: Workday with real-time webhooks (primary), Okta (secondary group cleanup).

Control attributePIP source field
user.employment_statusWorkday Worker_Status
user.activeOkta status
package controlcore.hr_terminate

import rego.v1

default allow := false

allow if {
  data.pip.workday.users[input.user.id].employment_status == "Active"
  data.pip.okta.users[input.user.id].status == "ACTIVE"
}

Without PIP: JWT exp can remain valid for hours. Terminated users retain API access until session expiry — a classic OSFI / SOC 2 access-revocation finding.

5. Defense clearance + compartment (CCCP L3)

Business context: A defence contractor protecting CUI-class APIs must enforce personnel clearance and compartment membership before tool or document access (CCCP Level 3 / CPCSC L2+ identity assurance).

PIPs required: LDAP or Okta (clearance), PostgreSQL or CMDB (compartment assignments).

Control attributePIP source field
user.clearance_levelLDAP clearance / Okta custom
user.compartmentsPostgres personnel_compartments
resource.compartmentResource metadata PIP
package controlcore.defense_compartment

import rego.v1

default allow := false

allow if {
  data.pip.identity.users[input.user.id].clearance_level in {"secret", "top_secret"}
  input.resource.compartment in data.pip.postgres.personnel_compartments[input.user.id]
}

Without PIP: Compartment membership cannot be proven at decision time. Gap reports emit CANNOT_ASSESS for CCCP identity controls.

6. Multi-tenant SaaS isolation

Business context: A SaaS platform hosts many customer tenants behind one Bouncer fleet. Controls must prove the caller's tenant matches the resource tenant — never trust a client-supplied tenant_id header alone.

PIPs required: PostgreSQL (tenant membership), Okta or Auth0 (org / tenant claims mirrored into PIP).

Control attributePIP source field
user.tenant_idsPostgres memberships.tenant_id
resource.tenant_idPostgres resources.tenant_id
package controlcore.tenant_isolation

import rego.v1

default allow := false

allow if {
  input.resource.tenant_id in data.pip.postgres.memberships[input.user.id]
}

Without PIP: Tenant isolation collapses to header checks — trivial to spoof. Cross-tenant data exposure becomes an auditor show-stopper.

7. Legacy LDAP → Okta dual-PIP migration

Business context: During IdP migration, some apps still resolve groups from LDAP while new apps use Okta. Controls must accept either authoritative source until cutover completes — without rewriting Rego twice.

PIPs required: LDAP and Okta, mapped to the same control attributes with documented precedence (see Multi-PIP composition).

Control attributeLDAP fieldOkta field
user.groupsmemberOfgroups
user.departmentdepartmentprofile.department
package controlcore.dual_idp

import rego.v1

default allow := false

_groups := data.pip.okta.users[input.user.id].groups if {
  data.pip.okta.users[input.user.id]
} else := data.pip.ldap.users[input.user.id].groups

allow if {
  "app-readers" in _groups
}

Without PIP (single source only): Half the user population fails open or closed during migration; cutover risk spikes and rollback is painful.

8. Multi-cloud data residency (Law 25 / PIPEDA)

Business context: Québec Law 25 and PIPEDA require that personal information processing stay in approved regions. Controls deny requests when the subject's residency region or the resource's storage region is outside the allowlist.

PIPs required: Okta/Azure AD (user residency / province), PostgreSQL or CMDB (resource region tags), optional Snowflake/BigQuery metadata PIP.

Control attributePIP source field
user.residency_regionIdP profile.province / usageLocation
resource.storage_regionCMDB / Postgres resources.region
package controlcore.data_residency

import rego.v1

default allow := false

_allowed := {"ca-central-1", "ca-west-1", "ca-on", "ca-qc"}

allow if {
  data.pip.identity.users[input.user.id].residency_region in _allowed
  data.pip.cmdb.resources[input.resource.id].storage_region in _allowed
}

Without PIP: Residency is guessed from IP or ignored. Law 25 §12 accountability and PIPEDA 4.7 safeguards cannot be evidenced in shadow or enforce modes.


Next: Configure attribute precedence and CANNOT_ASSESS behavior in the PIP Administrator Guide — Multi-PIP composition.

Understanding Multi-Bouncer Architecture

The Big Question: "We have 5 Bouncers protecting different apps - do we configure PIPs 5 times?"

Answer: NO! Configure ONCE, benefit EVERYWHERE!

Here's how it works:

You Configure (ONE TIME):
┌─────────────────────────────┐
│   Control Core PAP          │
│                             │
│   PIP Connections:          │
│   ✓ Okta                    │
│   ✓ PostgreSQL              │
│   ✓ Workday                 │
└──────────┬──────────────────┘
           │
           │ Publishes to Policy Bridge
           ▼
    ┌──────────────┐
    │ Policy Bridge│ ← Single source of truth
    └──────┬───────┘
           │
           │ Distributes to ALL Bouncers
           │
    ┌──────┼──────┬──────┬──────┐
    │      │      │      │      │
    ▼      ▼      ▼      ▼      ▼
┌────────┐ │  │  │  │  │  │  │  │
│Bouncer1│ │  │  │  │  │  │  │  │
│Protects│ │  │  │  │  │  │  │  │
│API A   │ │  │  │  │  │  │  │  │
└────────┘ │  │  │  │  │  │  │  │
    All bouncers automatically
    get the same fresh data!

Benefits:

  • Configure data sources ONCE in PAP
  • ALL Bouncers automatically receive the data
  • Consistent authorization decisions across all protected resources
  • Real-time updates propagate to all enforcement points

FAQs

Q: Is the metadata I see real or just examples?

A: It depends on whether you've tested the connection!

  • Before Testing: You see sample fields (examples of what might be available)
  • After Testing: You see REAL fields from your actual data source!

When you click "Test Connection" and it succeeds, the system:

  1. Connects to your Okta/Database/API
  2. Discovers the actual schema
  3. Shows you the real fields available

For example, after testing Okta, you'll see:

  • Your actual custom attributes
  • Your specific group names
  • Your configured profile fields

Q: Do I need to set up Authorization Attributes before connecting data sources?

A: NO! Authorization Attributes are pre-defined by Control Core.

The Authorization Attributes (like user.department, user.roles) are standard attribute names recommended by Control Core for policy writing. They're always available.

You just need to map them to your provider's field names:

  • user.department → Maps to → profile.department (in Okta)
  • user.department → Maps to → department (in Azure AD)

This standardization means your policies work with any provider!

Q: What if my data source isn't in the list?

You have options:

  1. Use "Custom API" - Works with any REST API
  2. Use "Custom" provider - Within each category
  3. Request Integration - Click "Request New Integration" button
  4. Contact Support - We can help build custom connectors

Q: How often should I sync data?

Recommendations:

  • Hourly: Good default for most use cases
  • Every 15 minutes: For frequently changing data
  • Real-time (Webhooks): For critical security decisions
  • Daily: For relatively static reference data

Rule of thumb: More frequent = more current data, but higher load on source systems

Q: Is my data secure?

Absolutely! Control Core uses enterprise-grade security:

  • Credentials Encrypted: AES-256 encryption for all stored credentials
  • TLS in Transit: All API calls use HTTPS/TLS
  • Secure Storage: Credentials stored separately from configuration
  • Audit Logging: Every data access is logged
  • Sensitivity-Based Caching: Sensitive data cached for shorter periods
  • No Plain Text: Passwords and secrets never stored unencrypted

Q: Can I edit a connection after it's created?

Yes! Go to Settings → Data Sources → Click on connection → Edit

You can change:

  • Authentication credentials
  • Sync frequency
  • Attribute mappings
  • Connection settings

Note: Changes take effect on the next sync cycle.

Q: What happens if a connection fails?

Control Core handles failures gracefully:

  1. Connection marked as "Error" - You'll see the status
  2. Policies still work - Use last cached data
  3. Alerts sent - Admins notified of failure
  4. Auto-retry - System attempts reconnection
  5. Audit logged - Failure details captured

You can manually retry or fix credentials and re-test.

Troubleshooting

IssueWhat to check
Connection test failsVerify URL, credentials, and network access from the Control Plane to the data source. Check firewall and TLS/SSL certificates.
Data not appearing in policiesConfirm attribute mappings and that the data source sync has completed. Check PIP status in Settings → Data Sources.
Sync errors or stale dataReview sync interval and retry; check data source rate limits and API availability. Inspect Control Plane logs for sync errors.
Multiple bouncers not receiving dataData is distributed from the Control Plane to all bouncers; ensure bouncers are registered and Policy Bridge is reachable.

For more, see the Troubleshooting Guide.

Next Steps

Now that you understand PIPs, you can:

  1. Connect More Sources: Add databases, HR systems, CRM
  2. Write Policies: Use your mapped attributes in policies
  3. Monitor Connections: Check sync status and health
  4. Optimize: Adjust sync frequencies based on usage

Need Help?

  • Admin Guide: For detailed configuration and monitoring
  • Developer Guide: For policy development and API integration
  • Support: Help & Support icon (?) in top navigation
  • Community: Join our Discord for questions and discussions

You've successfully connected your first data source! Your policies now have real-time context from your organization's systems.