[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill:01M6AF2N9HVADTYR28G5B5F576":3,"skill-same:01M6AF2N9HVADTYR28G5B5F576":105},{"skillNo":4,"name":5,"nameZh":6,"description":7,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":16,"categories":17,"keywords":28,"publishedAt":45,"linkOnly":46,"markdownContent":47,"markdownBody":48,"frontMatter":49,"refName":54,"commitSha":55,"skillDirectory":56,"forksCount":57,"repositoryHtmlUrl":58,"repositoryHomepageUrl":6,"ownerHtmlUrl":59,"ownerBlogUrl":60,"ownerDescription":61,"updatedAt":62,"install":63,"resources":76},"01M6AF2N9HVADTYR28G5B5F576","purpose-based-access",null,"Design and implement Purpose-Based Access Control (PBAC) architecture including purpose ontology definition, policy engine configuration, audit logging of purpose verification at query time, and integration with existing IAM systems. Enforces GDPR Article 5(1)(b) purpose limitation technically.","mukul975\u002FPrivacy-Data-Protection-Skills","mukul975","https:\u002F\u002Favatars.githubusercontent.com\u002Fu\u002F42860185?v=4","01M6ADEQR8T5M4EEG6C67BQCWF","Mahipal","01M6ADNKWX1HF4Q5DKEXT5M774",337,"Apache-2.0","https:\u002F\u002Fgithub.com\u002Fmukul975\u002FPrivacy-Data-Protection-Skills\u002Fblob\u002Fmain\u002Fplugins\u002Fprivacy-skills-complete\u002Fskills\u002Fpurpose-based-access\u002FSKILL.md",[18,23],{"categoryNo":19,"categoryName":20,"taxonomyType":21,"taxonomyTypeDesc":22},"01JBSEEDCAT000000000000015","视觉设计","SCENARIO","使用场景",{"categoryNo":24,"categoryName":25,"taxonomyType":26,"taxonomyTypeDesc":27},"01JBSEEDCAT000000000000032","设计师","PROFESSION","适用职业",[29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44],"purpose based access","design","policy","implement","architecture","policy engine","verification","logging","audit","integration","engineering","gdpr","privacy","access-control","iam","access-policy","2026-11-10 10:12:30",false,"---\nname: purpose-based-access\ndescription: >-\n  Design and implement Purpose-Based Access Control (PBAC) architecture including\n  purpose ontology definition, policy engine configuration, audit logging of\n  purpose verification at query time, and integration with existing IAM systems.\n  Enforces GDPR Article 5(1)(b) purpose limitation technically.\nlicense: Apache-2.0\nmetadata:\n  author: mukul975\n  version: \"1.0\"\n  domain: privacy\n  subdomain: privacy-engineering\n  tags: \"purpose-based-access-control, pbac, purpose-limitation, access-policy-engine, privacy-engineering\"\n---\n\n# Purpose-Based Access Control (PBAC) Architecture\n\n## Overview\n\nPurpose-Based Access Control (PBAC) extends traditional access control models (RBAC, ABAC) by adding purpose as a mandatory dimension in every access decision. Under PBAC, data access is granted only when the requester can demonstrate a valid, pre-authorized purpose that aligns with the basis under which the data was collected. This directly implements GDPR Article 5(1)(b) purpose limitation, CCPA purpose restrictions, and similar requirements across global privacy regulations.\n\n## PBAC vs Traditional Access Control\n\n| Dimension | RBAC | ABAC | PBAC |\n|-----------|------|------|------|\n| Access decision based on | Role membership | Attributes (user, resource, environment) | Purpose + attributes |\n| Answers the question | \"Who can access?\" | \"Under what conditions?\" | \"Why is this access needed?\" |\n| Purpose enforcement | None (implicit) | Possible as attribute | Core requirement |\n| Audit trail | Who accessed what | Who, what, when, where | Who, what, when, where, WHY |\n| Privacy alignment | Low | Medium | High |\n| Consent integration | None | Possible | Native |\n\n## Purpose Ontology\n\n### Purpose Hierarchy\n\n```\nRoot Purpose\n├── Service Delivery\n│   ├── Order Fulfillment\n│   │   ├── Payment Processing\n│   │   ├── Shipping Logistics\n│   │   └── Order Confirmation\n│   ├── Account Management\n│   │   ├── Account Creation\n│   │   ├── Account Maintenance\n│   │   └── Account Recovery\n│   └── Customer Support\n│       ├── Ticket Resolution\n│       └── Escalation Handling\n├── Legal Compliance\n│   ├── Regulatory Reporting\n│   │   ├── Tax Reporting\n│   │   ├── AML Compliance\n│   │   └── Regulatory Audit\n│   ├── Data Subject Rights\n│   │   ├── Access Request\n│   │   ├── Deletion Request\n│   │   ├── Portability Request\n│   │   └── Rectification Request\n│   └── Litigation Hold\n├── Analytics\n│   ├── Product Analytics\n│   │   ├── Feature Usage Analysis\n│   │   └── UX Research\n│   ├── Business Intelligence\n│   │   ├── Revenue Reporting\n│   │   └── Forecasting\n│   └── Aggregate Reporting\n│       ├── Board Reporting\n│       └── Investor Reporting\n├── Marketing\n│   ├── Direct Marketing\n│   │   ├── Email Campaigns\n│   │   └── Personalized Offers\n│   ├── Market Research\n│   │   └── Survey Analysis\n│   └── Advertising\n│       ├── Audience Segmentation\n│       └── Campaign Measurement\n└── Security\n    ├── Fraud Detection\n    ├── Incident Investigation\n    └── Access Auditing\n```\n\n### Purpose Definition Schema\n\n```python\nfrom dataclasses import dataclass, field\nfrom enum import Enum\nfrom datetime import datetime\n\n\nclass LegalBasis(Enum):\n    CONSENT = \"consent\"\n    CONTRACT = \"contract\"\n    LEGAL_OBLIGATION = \"legal_obligation\"\n    VITAL_INTEREST = \"vital_interest\"\n    PUBLIC_INTEREST = \"public_interest\"\n    LEGITIMATE_INTEREST = \"legitimate_interest\"\n\n\nclass PurposeStatus(Enum):\n    ACTIVE = \"active\"\n    DEPRECATED = \"deprecated\"\n    PENDING_APPROVAL = \"pending_approval\"\n\n\n@dataclass\nclass Purpose:\n    purpose_id: str\n    name: str\n    description: str\n    parent_purpose_id: str | None\n    legal_bases: list[LegalBasis]\n    data_categories_allowed: list[str]\n    retention_period_days: int\n    requires_consent: bool\n    status: PurposeStatus\n    owner: str\n    created_date: datetime\n    review_date: datetime\n    jurisdictions: list[str] = field(default_factory=lambda: [\"global\"])\n    compatible_purposes: list[str] = field(default_factory=list)\n    incompatible_purposes: list[str] = field(default_factory=list)\n```\n\n## Policy Engine Architecture\n\n### System Design\n\n```\nAccess Request\n    |\n    v\n+-------------------+\n| Request Parser    |\n| - Identity (who)  |\n| - Resource (what) |\n| - Action (how)    |\n| - Purpose (why)   |\n| - Context (when\u002F  |\n|   where)          |\n+-------------------+\n    |\n    v\n+-------------------+     +--------------------+\n| Purpose Validator |---->| Purpose Registry   |\n| - Purpose exists  |     | - Ontology tree    |\n| - Purpose active  |     | - Legal bases      |\n| - Purpose applies |     | - Data categories  |\n|   to data category|     +--------------------+\n+-------------------+\n    |\n    v\n+-------------------+     +--------------------+\n| Consent Checker   |---->| Consent Store      |\n| - Consent exists  |     | - Data subject     |\n| - Consent active  |     |   preferences      |\n| - Scope matches   |     | - Consent records  |\n+-------------------+     +--------------------+\n    |\n    v\n+-------------------+     +--------------------+\n| ABAC Policy       |---->| Policy Repository  |\n| Evaluator         |     | - XACML policies   |\n| - Role check      |     | - Purpose-data     |\n| - Attribute check  |     |   mappings        |\n| - Environment check|     +--------------------+\n+-------------------+\n    |\n    v\n+-------------------+\n| Decision Engine   |\n| - PERMIT \u002F DENY   |\n| - Obligations     |\n| - Advice          |\n+-------------------+\n    |\n    +------+-------+\n    |              |\n    v              v\nPERMIT          DENY\n+ Audit Log     + Audit Log\n+ Obligations   + Denial Reason\n```\n\n### Policy Engine Implementation\n\n```python\n\"\"\"\nPurpose-Based Access Control policy engine.\nEvaluates access requests against purpose definitions,\nconsent records, and attribute-based policies.\n\"\"\"\n\nfrom dataclasses import dataclass\nfrom datetime import datetime\nfrom enum import Enum\nfrom typing import Optional\n\n\nclass Decision(Enum):\n    PERMIT = \"PERMIT\"\n    DENY = \"DENY\"\n\n\n@dataclass\nclass AccessRequest:\n    requester_id: str\n    requester_roles: list[str]\n    resource_id: str\n    data_category: str\n    action: str  # read, write, delete, export\n    purpose_id: str\n    data_subject_id: Optional[str]\n    timestamp: datetime\n    source_ip: str\n    justification: str\n\n\n@dataclass\nclass AccessDecision:\n    decision: Decision\n    reason: str\n    obligations: list[str]\n    request: AccessRequest\n    evaluated_at: datetime\n    policy_version: str\n\n\nclass PurposeBasedAccessController:\n    \"\"\"\n    Core PBAC engine that evaluates access requests against\n    purpose definitions, consent records, and organizational policies.\n    \"\"\"\n\n    def __init__(\n        self,\n        purpose_registry,\n        consent_store,\n        policy_repository,\n        audit_logger\n    ):\n        self.purpose_registry = purpose_registry\n        self.consent_store = consent_store\n        self.policy_repository = policy_repository\n        self.audit_logger = audit_logger\n\n    def evaluate(self, request: AccessRequest) -> AccessDecision:\n        \"\"\"\n        Evaluate an access request through the PBAC pipeline.\n\n        Pipeline stages:\n        1. Purpose validation\n        2. Consent verification\n        3. Attribute-based policy evaluation\n        4. Decision with obligations\n        \"\"\"\n        now = datetime.utcnow()\n\n        # Stage 1: Validate purpose\n        purpose = self.purpose_registry.get_purpose(request.purpose_id)\n        if purpose is None:\n            return self._deny(request, \"Purpose not found in registry\", now)\n\n        if purpose.status != PurposeStatus.ACTIVE:\n            return self._deny(request, f\"Purpose is {purpose.status.value}\", now)\n\n        if request.data_category not in purpose.data_categories_allowed:\n            return self._deny(\n                request,\n                f\"Data category '{request.data_category}' not allowed for purpose '{purpose.name}'\",\n                now\n            )\n\n        # Stage 2: Verify consent (if required)\n        if purpose.requires_consent and request.data_subject_id:\n            consent = self.consent_store.get_active_consent(\n                data_subject_id=request.data_subject_id,\n                purpose_id=request.purpose_id\n            )\n            if consent is None:\n                return self._deny(\n                    request,\n                    f\"No active consent for purpose '{purpose.name}' from data subject\",\n                    now\n                )\n\n        # Stage 3: Evaluate attribute-based policies\n        policy_result = self.policy_repository.evaluate(\n            roles=request.requester_roles,\n            resource=request.resource_id,\n            action=request.action,\n            purpose=request.purpose_id,\n            data_category=request.data_category,\n            context={\"source_ip\": request.source_ip, \"time\": now}\n        )\n\n        if not policy_result.permitted:\n            return self._deny(request, policy_result.denial_reason, now)\n\n        # Stage 4: Permit with obligations\n        obligations = self._determine_obligations(purpose, request)\n        decision = AccessDecision(\n            decision=Decision.PERMIT,\n            reason=f\"Access permitted for purpose '{purpose.name}'\",\n            obligations=obligations,\n            request=request,\n            evaluated_at=now,\n            policy_version=self.policy_repository.version\n        )\n\n        self.audit_logger.log_access_decision(decision)\n        return decision\n\n    def _deny(\n        self, request: AccessRequest, reason: str, timestamp: datetime\n    ) -> AccessDecision:\n        \"\"\"Create a DENY decision and log it.\"\"\"\n        decision = AccessDecision(\n            decision=Decision.DENY,\n            reason=reason,\n            obligations=[],\n            request=request,\n            evaluated_at=timestamp,\n            policy_version=self.policy_repository.version\n        )\n        self.audit_logger.log_access_decision(decision)\n        return decision\n\n    def _determine_obligations(self, purpose, request: AccessRequest) -> list[str]:\n        \"\"\"Determine post-access obligations based on purpose and context.\"\"\"\n        obligations = []\n\n        if request.action == \"export\":\n            obligations.append(\"LOG_DATA_EXPORT\")\n            obligations.append(\"APPLY_ENCRYPTION_TO_EXPORT\")\n\n        if request.action == \"read\" and request.data_category in [\n            \"health_data\", \"financial_data\", \"biometric_data\"\n        ]:\n            obligations.append(\"MASK_SENSITIVE_FIELDS\")\n\n        obligations.append(f\"ENFORCE_RETENTION_{purpose.retention_period_days}_DAYS\")\n        obligations.append(\"LOG_PURPOSE_USAGE\")\n\n        return obligations\n```\n\n## Purpose Verification at Query Time\n\n### SQL Proxy with Purpose Enforcement\n\n```python\n\"\"\"\nSQL proxy that intercepts database queries and enforces\npurpose-based access control at the query level.\n\"\"\"\n\nimport re\nfrom datetime import datetime\n\n\nclass PurposeAwareSQLProxy:\n    \"\"\"\n    Intercepts SQL queries, validates purpose, and rewrites\n    queries to enforce data category restrictions.\n    \"\"\"\n\n    def __init__(self, pbac_controller, column_category_map: dict):\n        self.pbac = pbac_controller\n        self.column_category_map = column_category_map\n\n    def execute_query(\n        self,\n        sql: str,\n        requester_id: str,\n        requester_roles: list[str],\n        purpose_id: str,\n        justification: str\n    ) -> tuple[bool, object]:\n        \"\"\"\n        Execute a SQL query with purpose verification.\n\n        Returns (success, result_or_error).\n        \"\"\"\n        # Parse referenced columns\u002Ftables from SQL\n        referenced_columns = self._extract_columns(sql)\n        referenced_categories = set()\n\n        for col in referenced_columns:\n            category = self.column_category_map.get(col, \"general\")\n            referenced_categories.add(category)\n\n        # Validate access for each data category\n        denied_categories = []\n        for category in referenced_categories:\n            request = AccessRequest(\n                requester_id=requester_id,\n                requester_roles=requester_roles,\n                resource_id=\"database\",\n                data_category=category,\n                action=\"read\",\n                purpose_id=purpose_id,\n                data_subject_id=None,\n                timestamp=datetime.utcnow(),\n                source_ip=\"internal\",\n                justification=justification\n            )\n\n            decision = self.pbac.evaluate(request)\n            if decision.decision == Decision.DENY:\n                denied_categories.append((category, decision.reason))\n\n        if denied_categories:\n            reasons = \"; \".join(\n                f\"{cat}: {reason}\" for cat, reason in denied_categories\n            )\n            return (False, f\"Access denied for categories: {reasons}\")\n\n        # Rewrite query to mask unauthorized columns if needed\n        rewritten_sql = self._apply_column_masking(sql, purpose_id)\n\n        # Execute the rewritten query (actual DB execution would go here)\n        return (True, rewritten_sql)\n\n    def _extract_columns(self, sql: str) -> list[str]:\n        \"\"\"Extract column references from SQL (simplified parser).\"\"\"\n        select_pattern = re.compile(\n            r\"SELECT\\s+(.+?)\\s+FROM\", re.IGNORECASE | re.DOTALL\n        )\n        match = select_pattern.search(sql)\n        if not match:\n            return []\n\n        columns_str = match.group(1)\n        if columns_str.strip() == \"*\":\n            return list(self.column_category_map.keys())\n\n        columns = [\n            col.strip().split(\".\")[-1].split(\" \")[0]\n            for col in columns_str.split(\",\")\n        ]\n        return columns\n\n    def _apply_column_masking(self, sql: str, purpose_id: str) -> str:\n        \"\"\"Rewrite query to mask columns not needed for the given purpose.\"\"\"\n        return sql  # Production implementation would rewrite SELECT columns\n```\n\n## Audit Logging for PBAC\n\n### Audit Record Schema\n\n| Field | Type | Description |\n|-------|------|-------------|\n| audit_id | UUID | Unique audit record identifier |\n| timestamp | DateTime | When the access decision was made |\n| requester_id | String | Identity of the requester |\n| requester_roles | Array[String] | Roles held by requester |\n| resource_id | String | Resource being accessed |\n| data_category | String | Category of data being accessed |\n| action | String | Type of access (read\u002Fwrite\u002Fdelete\u002Fexport) |\n| purpose_id | String | Stated purpose for access |\n| purpose_name | String | Human-readable purpose name |\n| decision | Enum | PERMIT or DENY |\n| denial_reason | String | Reason for denial (if denied) |\n| obligations | Array[String] | Post-access obligations applied |\n| justification | String | Free-text justification from requester |\n| policy_version | String | Version of policy used for decision |\n\n## Integration with Existing IAM\n\n### PBAC Overlay Architecture\n\n```\nExisting IAM (RBAC\u002FABAC)\n    |\n    v\n+---------------------------+\n| PBAC Middleware Layer      |\n| (intercepts access calls) |\n+---------------------------+\n    |\n    +-- Purpose verification\n    +-- Consent validation\n    +-- Data category mapping\n    +-- Obligation enforcement\n    +-- Enhanced audit logging\n    |\n    v\nResource (Database \u002F API \u002F File System)\n```\n\n## References\n\n- Byun, J. and Li, N. \"Purpose Based Access Control of Complex Data for Privacy Protection.\" ACM SACMAT, 2008.\n- GDPR Article 5(1)(b) — Purpose Limitation Principle\n- ISO\u002FIEC 29101:2018 — Privacy Architecture Framework\n- NIST SP 800-162 — Guide to Attribute Based Access Control Definition and Considerations\n- Ni, Q. et al. \"Privacy-Aware Role-Based Access Control.\" ACM TOPS, 2010.\n","# Purpose-Based Access Control (PBAC) Architecture\n\n## Overview\n\nPurpose-Based Access Control (PBAC) extends traditional access control models (RBAC, ABAC) by adding purpose as a mandatory dimension in every access decision. Under PBAC, data access is granted only when the requester can demonstrate a valid, pre-authorized purpose that aligns with the basis under which the data was collected. This directly implements GDPR Article 5(1)(b) purpose limitation, CCPA purpose restrictions, and similar requirements across global privacy regulations.\n\n## PBAC vs Traditional Access Control\n\n| Dimension | RBAC | ABAC | PBAC |\n|-----------|------|------|------|\n| Access decision based on | Role membership | Attributes (user, resource, environment) | Purpose + attributes |\n| Answers the question | \"Who can access?\" | \"Under what conditions?\" | \"Why is this access needed?\" |\n| Purpose enforcement | None (implicit) | Possible as attribute | Core requirement |\n| Audit trail | Who accessed what | Who, what, when, where | Who, what, when, where, WHY |\n| Privacy alignment | Low | Medium | High |\n| Consent integration | None | Possible | Native |\n\n## Purpose Ontology\n\n### Purpose Hierarchy\n\n```\nRoot Purpose\n├── Service Delivery\n│   ├── Order Fulfillment\n│   │   ├── Payment Processing\n│   │   ├── Shipping Logistics\n│   │   └── Order Confirmation\n│   ├── Account Management\n│   │   ├── Account Creation\n│   │   ├── Account Maintenance\n│   │   └── Account Recovery\n│   └── Customer Support\n│       ├── Ticket Resolution\n│       └── Escalation Handling\n├── Legal Compliance\n│   ├── Regulatory Reporting\n│   │   ├── Tax Reporting\n│   │   ├── AML Compliance\n│   │   └── Regulatory Audit\n│   ├── Data Subject Rights\n│   │   ├── Access Request\n│   │   ├── Deletion Request\n│   │   ├── Portability Request\n│   │   └── Rectification Request\n│   └── Litigation Hold\n├── Analytics\n│   ├── Product Analytics\n│   │   ├── Feature Usage Analysis\n│   │   └── UX Research\n│   ├── Business Intelligence\n│   │   ├── Revenue Reporting\n│   │   └── Forecasting\n│   └── Aggregate Reporting\n│       ├── Board Reporting\n│       └── Investor Reporting\n├── Marketing\n│   ├── Direct Marketing\n│   │   ├── Email Campaigns\n│   │   └── Personalized Offers\n│   ├── Market Research\n│   │   └── Survey Analysis\n│   └── Advertising\n│       ├── Audience Segmentation\n│       └── Campaign Measurement\n└── Security\n    ├── Fraud Detection\n    ├── Incident Investigation\n    └── Access Auditing\n```\n\n### Purpose Definition Schema\n\n```python\nfrom dataclasses import dataclass, field\nfrom enum import Enum\nfrom datetime import datetime\n\n\nclass LegalBasis(Enum):\n    CONSENT = \"consent\"\n    CONTRACT = \"contract\"\n    LEGAL_OBLIGATION = \"legal_obligation\"\n    VITAL_INTEREST = \"vital_interest\"\n    PUBLIC_INTEREST = \"public_interest\"\n    LEGITIMATE_INTEREST = \"legitimate_interest\"\n\n\nclass PurposeStatus(Enum):\n    ACTIVE = \"active\"\n    DEPRECATED = \"deprecated\"\n    PENDING_APPROVAL = \"pending_approval\"\n\n\n@dataclass\nclass Purpose:\n    purpose_id: str\n    name: str\n    description: str\n    parent_purpose_id: str | None\n    legal_bases: list[LegalBasis]\n    data_categories_allowed: list[str]\n    retention_period_days: int\n    requires_consent: bool\n    status: PurposeStatus\n    owner: str\n    created_date: datetime\n    review_date: datetime\n    jurisdictions: list[str] = field(default_factory=lambda: [\"global\"])\n    compatible_purposes: list[str] = field(default_factory=list)\n    incompatible_purposes: list[str] = field(default_factory=list)\n```\n\n## Policy Engine Architecture\n\n### System Design\n\n```\nAccess Request\n    |\n    v\n+-------------------+\n| Request Parser    |\n| - Identity (who)  |\n| - Resource (what) |\n| - Action (how)    |\n| - Purpose (why)   |\n| - Context (when\u002F  |\n|   where)          |\n+-------------------+\n    |\n    v\n+-------------------+     +--------------------+\n| Purpose Validator |---->| Purpose Registry   |\n| - Purpose exists  |     | - Ontology tree    |\n| - Purpose active  |     | - Legal bases      |\n| - Purpose applies |     | - Data categories  |\n|   to data category|     +--------------------+\n+-------------------+\n    |\n    v\n+-------------------+     +--------------------+\n| Consent Checker   |---->| Consent Store      |\n| - Consent exists  |     | - Data subject     |\n| - Consent active  |     |   preferences      |\n| - Scope matches   |     | - Consent records  |\n+-------------------+     +--------------------+\n    |\n    v\n+-------------------+     +--------------------+\n| ABAC Policy       |---->| Policy Repository  |\n| Evaluator         |     | - XACML policies   |\n| - Role check      |     | - Purpose-data     |\n| - Attribute check  |     |   mappings        |\n| - Environment check|     +--------------------+\n+-------------------+\n    |\n    v\n+-------------------+\n| Decision Engine   |\n| - PERMIT \u002F DENY   |\n| - Obligations     |\n| - Advice          |\n+-------------------+\n    |\n    +------+-------+\n    |              |\n    v              v\nPERMIT          DENY\n+ Audit Log     + Audit Log\n+ Obligations   + Denial Reason\n```\n\n### Policy Engine Implementation\n\n```python\n\"\"\"\nPurpose-Based Access Control policy engine.\nEvaluates access requests against purpose definitions,\nconsent records, and attribute-based policies.\n\"\"\"\n\nfrom dataclasses import dataclass\nfrom datetime import datetime\nfrom enum import Enum\nfrom typing import Optional\n\n\nclass Decision(Enum):\n    PERMIT = \"PERMIT\"\n    DENY = \"DENY\"\n\n\n@dataclass\nclass AccessRequest:\n    requester_id: str\n    requester_roles: list[str]\n    resource_id: str\n    data_category: str\n    action: str  # read, write, delete, export\n    purpose_id: str\n    data_subject_id: Optional[str]\n    timestamp: datetime\n    source_ip: str\n    justification: str\n\n\n@dataclass\nclass AccessDecision:\n    decision: Decision\n    reason: str\n    obligations: list[str]\n    request: AccessRequest\n    evaluated_at: datetime\n    policy_version: str\n\n\nclass PurposeBasedAccessController:\n    \"\"\"\n    Core PBAC engine that evaluates access requests against\n    purpose definitions, consent records, and organizational policies.\n    \"\"\"\n\n    def __init__(\n        self,\n        purpose_registry,\n        consent_store,\n        policy_repository,\n        audit_logger\n    ):\n        self.purpose_registry = purpose_registry\n        self.consent_store = consent_store\n        self.policy_repository = policy_repository\n        self.audit_logger = audit_logger\n\n    def evaluate(self, request: AccessRequest) -> AccessDecision:\n        \"\"\"\n        Evaluate an access request through the PBAC pipeline.\n\n        Pipeline stages:\n        1. Purpose validation\n        2. Consent verification\n        3. Attribute-based policy evaluation\n        4. Decision with obligations\n        \"\"\"\n        now = datetime.utcnow()\n\n        # Stage 1: Validate purpose\n        purpose = self.purpose_registry.get_purpose(request.purpose_id)\n        if purpose is None:\n            return self._deny(request, \"Purpose not found in registry\", now)\n\n        if purpose.status != PurposeStatus.ACTIVE:\n            return self._deny(request, f\"Purpose is {purpose.status.value}\", now)\n\n        if request.data_category not in purpose.data_categories_allowed:\n            return self._deny(\n                request,\n                f\"Data category '{request.data_category}' not allowed for purpose '{purpose.name}'\",\n                now\n            )\n\n        # Stage 2: Verify consent (if required)\n        if purpose.requires_consent and request.data_subject_id:\n            consent = self.consent_store.get_active_consent(\n                data_subject_id=request.data_subject_id,\n                purpose_id=request.purpose_id\n            )\n            if consent is None:\n                return self._deny(\n                    request,\n                    f\"No active consent for purpose '{purpose.name}' from data subject\",\n                    now\n                )\n\n        # Stage 3: Evaluate attribute-based policies\n        policy_result = self.policy_repository.evaluate(\n            roles=request.requester_roles,\n            resource=request.resource_id,\n            action=request.action,\n            purpose=request.purpose_id,\n            data_category=request.data_category,\n            context={\"source_ip\": request.source_ip, \"time\": now}\n        )\n\n        if not policy_result.permitted:\n            return self._deny(request, policy_result.denial_reason, now)\n\n        # Stage 4: Permit with obligations\n        obligations = self._determine_obligations(purpose, request)\n        decision = AccessDecision(\n            decision=Decision.PERMIT,\n            reason=f\"Access permitted for purpose '{purpose.name}'\",\n            obligations=obligations,\n            request=request,\n            evaluated_at=now,\n            policy_version=self.policy_repository.version\n        )\n\n        self.audit_logger.log_access_decision(decision)\n        return decision\n\n    def _deny(\n        self, request: AccessRequest, reason: str, timestamp: datetime\n    ) -> AccessDecision:\n        \"\"\"Create a DENY decision and log it.\"\"\"\n        decision = AccessDecision(\n            decision=Decision.DENY,\n            reason=reason,\n            obligations=[],\n            request=request,\n            evaluated_at=timestamp,\n            policy_version=self.policy_repository.version\n        )\n        self.audit_logger.log_access_decision(decision)\n        return decision\n\n    def _determine_obligations(self, purpose, request: AccessRequest) -> list[str]:\n        \"\"\"Determine post-access obligations based on purpose and context.\"\"\"\n        obligations = []\n\n        if request.action == \"export\":\n            obligations.append(\"LOG_DATA_EXPORT\")\n            obligations.append(\"APPLY_ENCRYPTION_TO_EXPORT\")\n\n        if request.action == \"read\" and request.data_category in [\n            \"health_data\", \"financial_data\", \"biometric_data\"\n        ]:\n            obligations.append(\"MASK_SENSITIVE_FIELDS\")\n\n        obligations.append(f\"ENFORCE_RETENTION_{purpose.retention_period_days}_DAYS\")\n        obligations.append(\"LOG_PURPOSE_USAGE\")\n\n        return obligations\n```\n\n## Purpose Verification at Query Time\n\n### SQL Proxy with Purpose Enforcement\n\n```python\n\"\"\"\nSQL proxy that intercepts database queries and enforces\npurpose-based access control at the query level.\n\"\"\"\n\nimport re\nfrom datetime import datetime\n\n\nclass PurposeAwareSQLProxy:\n    \"\"\"\n    Intercepts SQL queries, validates purpose, and rewrites\n    queries to enforce data category restrictions.\n    \"\"\"\n\n    def __init__(self, pbac_controller, column_category_map: dict):\n        self.pbac = pbac_controller\n        self.column_category_map = column_category_map\n\n    def execute_query(\n        self,\n        sql: str,\n        requester_id: str,\n        requester_roles: list[str],\n        purpose_id: str,\n        justification: str\n    ) -> tuple[bool, object]:\n        \"\"\"\n        Execute a SQL query with purpose verification.\n\n        Returns (success, result_or_error).\n        \"\"\"\n        # Parse referenced columns\u002Ftables from SQL\n        referenced_columns = self._extract_columns(sql)\n        referenced_categories = set()\n\n        for col in referenced_columns:\n            category = self.column_category_map.get(col, \"general\")\n            referenced_categories.add(category)\n\n        # Validate access for each data category\n        denied_categories = []\n        for category in referenced_categories:\n            request = AccessRequest(\n                requester_id=requester_id,\n                requester_roles=requester_roles,\n                resource_id=\"database\",\n                data_category=category,\n                action=\"read\",\n                purpose_id=purpose_id,\n                data_subject_id=None,\n                timestamp=datetime.utcnow(),\n                source_ip=\"internal\",\n                justification=justification\n            )\n\n            decision = self.pbac.evaluate(request)\n            if decision.decision == Decision.DENY:\n                denied_categories.append((category, decision.reason))\n\n        if denied_categories:\n            reasons = \"; \".join(\n                f\"{cat}: {reason}\" for cat, reason in denied_categories\n            )\n            return (False, f\"Access denied for categories: {reasons}\")\n\n        # Rewrite query to mask unauthorized columns if needed\n        rewritten_sql = self._apply_column_masking(sql, purpose_id)\n\n        # Execute the rewritten query (actual DB execution would go here)\n        return (True, rewritten_sql)\n\n    def _extract_columns(self, sql: str) -> list[str]:\n        \"\"\"Extract column references from SQL (simplified parser).\"\"\"\n        select_pattern = re.compile(\n            r\"SELECT\\s+(.+?)\\s+FROM\", re.IGNORECASE | re.DOTALL\n        )\n        match = select_pattern.search(sql)\n        if not match:\n            return []\n\n        columns_str = match.group(1)\n        if columns_str.strip() == \"*\":\n            return list(self.column_category_map.keys())\n\n        columns = [\n            col.strip().split(\".\")[-1].split(\" \")[0]\n            for col in columns_str.split(\",\")\n        ]\n        return columns\n\n    def _apply_column_masking(self, sql: str, purpose_id: str) -> str:\n        \"\"\"Rewrite query to mask columns not needed for the given purpose.\"\"\"\n        return sql  # Production implementation would rewrite SELECT columns\n```\n\n## Audit Logging for PBAC\n\n### Audit Record Schema\n\n| Field | Type | Description |\n|-------|------|-------------|\n| audit_id | UUID | Unique audit record identifier |\n| timestamp | DateTime | When the access decision was made |\n| requester_id | String | Identity of the requester |\n| requester_roles | Array[String] | Roles held by requester |\n| resource_id | String | Resource being accessed |\n| data_category | String | Category of data being accessed |\n| action | String | Type of access (read\u002Fwrite\u002Fdelete\u002Fexport) |\n| purpose_id | String | Stated purpose for access |\n| purpose_name | String | Human-readable purpose name |\n| decision | Enum | PERMIT or DENY |\n| denial_reason | String | Reason for denial (if denied) |\n| obligations | Array[String] | Post-access obligations applied |\n| justification | String | Free-text justification from requester |\n| policy_version | String | Version of policy used for decision |\n\n## Integration with Existing IAM\n\n### PBAC Overlay Architecture\n\n```\nExisting IAM (RBAC\u002FABAC)\n    |\n    v\n+---------------------------+\n| PBAC Middleware Layer      |\n| (intercepts access calls) |\n+---------------------------+\n    |\n    +-- Purpose verification\n    +-- Consent validation\n    +-- Data category mapping\n    +-- Obligation enforcement\n    +-- Enhanced audit logging\n    |\n    v\nResource (Database \u002F API \u002F File System)\n```\n\n## References\n\n- Byun, J. and Li, N. \"Purpose Based Access Control of Complex Data for Privacy Protection.\" ACM SACMAT, 2008.\n- GDPR Article 5(1)(b) — Purpose Limitation Principle\n- ISO\u002FIEC 29101:2018 — Privacy Architecture Framework\n- NIST SP 800-162 — Guide to Attribute Based Access Control Definition and Considerations\n- Ni, Q. et al. \"Privacy-Aware Role-Based Access Control.\" ACM TOPS, 2010.\n",{"name":5,"license":15,"metadata":50,"description":7},{"tags":51,"author":9,"domain":41,"version":52,"subdomain":53},"purpose-based-access-control, pbac, purpose-limitation, access-policy-engine, privacy-engineering","1.0","privacy-engineering","main","9b2ef9eae161c00a17241d42a388571321b33e9f","plugins\u002Fprivacy-skills-complete\u002Fskills\u002Fpurpose-based-access",68,"https:\u002F\u002Fgithub.com\u002Fmukul975\u002FPrivacy-Data-Protection-Skills","https:\u002F\u002Fgithub.com\u002Fmukul975","Mahipal.engineer","🔐 Cybersecurity | 💻 Dev | 📷 Street Photographer\r\n🎓 MSc | 📚 Research & AI Security","2026-03-17 04:06:52",{"source":8,"skillName":5,"commands":64,"prompt":74,"zipAvailable":75},[65,68,71],{"tool":66,"command":67},"npx","npx skills add mukul975\u002FPrivacy-Data-Protection-Skills --skill purpose-based-access",{"tool":69,"command":70},"bunx","bunx skills add mukul975\u002FPrivacy-Data-Protection-Skills --skill purpose-based-access",{"tool":72,"command":73},"pnpm","pnpm dlx skills add mukul975\u002FPrivacy-Data-Protection-Skills --skill purpose-based-access","安装技能，技能地址：https:\u002F\u002Fgithub.com\u002Fmukul975\u002FPrivacy-Data-Protection-Skills\u002Fblob\u002Fmain\u002Fplugins\u002Fprivacy-skills-complete\u002Fskills\u002Fpurpose-based-access\u002FSKILL.md",true,[77,83,89,93,99],{"path":78,"resourceType":79,"resourceTypeDesc":80,"sizeBytes":81,"sourceHtmlUrl":82},"assets\u002Ftemplate.md","ASSET","资产文件",744,"https:\u002F\u002Fgithub.com\u002Fmukul975\u002FPrivacy-Data-Protection-Skills\u002Fblob\u002Fmain\u002Fplugins\u002Fprivacy-skills-complete\u002Fskills\u002Fpurpose-based-access\u002Fassets\u002Ftemplate.md",{"path":84,"resourceType":85,"resourceTypeDesc":86,"sizeBytes":87,"sourceHtmlUrl":88},"references\u002Fstandards.md","REFERENCE","参考文档",863,"https:\u002F\u002Fgithub.com\u002Fmukul975\u002FPrivacy-Data-Protection-Skills\u002Fblob\u002Fmain\u002Fplugins\u002Fprivacy-skills-complete\u002Fskills\u002Fpurpose-based-access\u002Freferences\u002Fstandards.md",{"path":90,"resourceType":85,"resourceTypeDesc":86,"sizeBytes":91,"sourceHtmlUrl":92},"references\u002Fworkflows.md",1104,"https:\u002F\u002Fgithub.com\u002Fmukul975\u002FPrivacy-Data-Protection-Skills\u002Fblob\u002Fmain\u002Fplugins\u002Fprivacy-skills-complete\u002Fskills\u002Fpurpose-based-access\u002Freferences\u002Fworkflows.md",{"path":94,"resourceType":95,"resourceTypeDesc":96,"sizeBytes":97,"sourceHtmlUrl":98},"scripts\u002Fprocess.py","SCRIPT","脚本",7255,"https:\u002F\u002Fgithub.com\u002Fmukul975\u002FPrivacy-Data-Protection-Skills\u002Fblob\u002Fmain\u002Fplugins\u002Fprivacy-skills-complete\u002Fskills\u002Fpurpose-based-access\u002Fscripts\u002Fprocess.py",{"path":100,"resourceType":101,"resourceTypeDesc":102,"sizeBytes":103,"sourceHtmlUrl":104},"sections","OTHER","其他",65,"https:\u002F\u002Fgithub.com\u002Fnoirelab\u002Flinux-setup\u002Fblob\u002Fmain\u002Fconfigs\u002Fcommon\u002Fclaude\u002Fskills\u002Fdesign-consultation\u002Fsections",[106,130,146,158,175,188],{"skillNo":107,"name":108,"nameZh":6,"description":109,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":110,"categories":111,"keywords":121,"publishedAt":45},"01M6AG6K8R3XW10ENWH2FH18RH","workplace-email-privacy","Implements email and internet monitoring compliance in the workplace per Barbulescu v Romania (ECHR Grand Chamber), EDPB guidance, and national labour law. Covers acceptable use policies, legitimate expectation of privacy, proportionality testing, and content vs metadata monitoring. Keywords: email monitoring, Barbulescu, workplace privacy, internet monitoring, acceptable use policy, ECHR, proportionality.","https:\u002F\u002Fgithub.com\u002Fmukul975\u002FPrivacy-Data-Protection-Skills\u002Fblob\u002Fmain\u002Fskills\u002Fprivacy\u002Fworkplace-email-privacy\u002FSKILL.md",[112,115,118],{"categoryNo":113,"categoryName":114,"taxonomyType":21,"taxonomyTypeDesc":22},"01JBSEEDCAT000000000000005","邮件与沟通",{"categoryNo":116,"categoryName":117,"taxonomyType":21,"taxonomyTypeDesc":22},"01JBSEEDCAT000000000000008","测试与质量",{"categoryNo":119,"categoryName":120,"taxonomyType":26,"taxonomyTypeDesc":27},"01JBSEEDCAT000000000000037","律师与法务",[122,123,41,124,125,126,31,127,128,129],"email","workplace email privacy","compliance","content","data","testing","monitoring","metadata",{"skillNo":131,"name":132,"nameZh":6,"description":133,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":134,"categories":135,"keywords":140,"publishedAt":45},"01M6AG6FRCBJY7D061BJZMNV49","whistleblower-data","Implements data protection compliance for whistleblowing systems under EU Directive 2019\u002F1937 and GDPR. Covers anonymous reporting channels, identity protection for whistleblowers and accused persons, retention limits, access restrictions, and retaliation prevention. Addresses national transpositions and DPA guidance. Keywords: whistleblower, Directive 2019\u002F1937, anonymous reporting, identity protection, retaliation, retention, reporting channel.","https:\u002F\u002Fgithub.com\u002Fmukul975\u002FPrivacy-Data-Protection-Skills\u002Fblob\u002Fmain\u002Fskills\u002Fprivacy\u002Fwhistleblower-data\u002FSKILL.md",[136,139],{"categoryNo":137,"categoryName":138,"taxonomyType":26,"taxonomyTypeDesc":27},"01JBSEEDCAT000000000000033","数据分析师",{"categoryNo":119,"categoryName":120,"taxonomyType":26,"taxonomyTypeDesc":27},[126,141,142,143,124,144,40,41,145],"whistleblower data","identity","reporting","data protection","prevention",{"skillNo":147,"name":148,"nameZh":6,"description":149,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":150,"categories":151,"keywords":153,"publishedAt":45},"01M6AG6CJP0PW3X65HC7VP9SR9","vendor-termination-data","Vendor termination data return and deletion procedures per GDPR Article 28(3)(g). Covers data extraction formats, deletion certification requirements, transition planning, residual data handling, and post-termination verification.","https:\u002F\u002Fgithub.com\u002Fmukul975\u002FPrivacy-Data-Protection-Skills\u002Fblob\u002Fmain\u002Fskills\u002Fprivacy\u002Fvendor-termination-data\u002FSKILL.md",[152],{"categoryNo":137,"categoryName":138,"taxonomyType":26,"taxonomyTypeDesc":27},[126,154,155,35,156,40,41,157],"vendor termination data","planning","extraction","certification",{"skillNo":159,"name":160,"nameZh":6,"description":161,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":162,"categories":163,"keywords":165,"publishedAt":45},"01M6AG69E277DXZB2NF6KV17ZA","vendor-risk-scoring","Vendor privacy risk tiering methodology for processor management. Covers scoring factors including data volume, sensitivity, transfer locations, certifications, breach history, and control maturity with weighted risk calculation and tier assignment.","https:\u002F\u002Fgithub.com\u002Fmukul975\u002FPrivacy-Data-Protection-Skills\u002Fblob\u002Fmain\u002Fskills\u002Fprivacy\u002Fvendor-risk-scoring\u002FSKILL.md",[164],{"categoryNo":137,"categoryName":138,"taxonomyType":26,"taxonomyTypeDesc":27},[166,167,168,169,170,171,172,173,41,126,174],"vendor risk scoring","risk","risk scoring","methodology","risk-scoring","assessment","transfer","certifications","processor",{"skillNo":176,"name":177,"nameZh":6,"description":178,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":179,"categories":180,"keywords":182,"publishedAt":45},"01M6AG6655ABFKT2BBWHCP4PAT","vendor-privacy-due-diligence","Pre-contract vendor privacy due diligence per GDPR Article 28(1). Covers risk questionnaires, technical controls assessment, certification review, data flow analysis, and documented sufficiency decisions for processor engagement.","https:\u002F\u002Fgithub.com\u002Fmukul975\u002FPrivacy-Data-Protection-Skills\u002Fblob\u002Fmain\u002Fskills\u002Fprivacy\u002Fvendor-privacy-due-diligence\u002FSKILL.md",[181],{"categoryNo":119,"categoryName":120,"taxonomyType":26,"taxonomyTypeDesc":27},[41,183,40,184,171,185,186,126,174,167,157,187],"vendor privacy due diligence","review","onboarding","flow","analysis",{"skillNo":189,"name":190,"nameZh":6,"description":191,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":192,"categories":193,"keywords":201,"publishedAt":45},"01M6AG62C3VD8SYNGH4N7RHZTE","vendor-privacy-audit","On-site and remote vendor audit procedures per GDPR Article 28(3)(h). Covers audit planning, evidence collection methodologies, finding classification, remediation tracking, and audit report generation for processor compliance verification.","https:\u002F\u002Fgithub.com\u002Fmukul975\u002FPrivacy-Data-Protection-Skills\u002Fblob\u002Fmain\u002Fskills\u002Fprivacy\u002Fvendor-privacy-audit\u002FSKILL.md",[194,197,200],{"categoryNo":195,"categoryName":196,"taxonomyType":21,"taxonomyTypeDesc":22},"01JBSEEDCAT000000000000018","写作与文案",{"categoryNo":198,"categoryName":199,"taxonomyType":26,"taxonomyTypeDesc":27},"01JBSEEDCAT000000000000036","内容创作者",{"categoryNo":119,"categoryName":120,"taxonomyType":26,"taxonomyTypeDesc":27},[202,37,41,203,35,204,124,40,205,174,206,207,208,155],"vendor privacy audit","report","audit report","remediation","collection","remediation-tracking","classification"]