BINDY_ROLE_YAML

Constant BINDY_ROLE_YAML 

Source
pub const BINDY_ROLE_YAML: &str = "# Copyright (c) 2025 Erick Bourgeois, firestoned\n# SPDX-License-Identifier: MIT\n---\napiVersion: rbac.authorization.k8s.io/v1\nkind: ClusterRole\nmetadata:\n  name: bindy-role\n  labels:\n    app.kubernetes.io/name: bindy\n    app.kubernetes.io/component: rbac\n  annotations:\n    # Trivy suppressions - see inline justifications at affected rules\n    trivy.aquasecurity.com/ignore: KSV-0041,KSV-0056\nrules:\n  # Bind9Instance resources\n  - apiGroups: [\"bindy.firestoned.io\"]\n    resources: [\"bind9instances\"]\n    verbs: [\"get\", \"list\", \"watch\", \"create\", \"update\", \"patch\", \"delete\"]\n    # Permissions needed:\n    # - \"get\", \"list\", \"watch\": Read instances for status updates\n    # - \"create\": Create instances for Bind9Cluster scaling\n    # - \"update\", \"patch\": Update instance configuration\n    # - \"delete\": Scale down instances (Bind9Cluster reconciler) and finalizer cleanup\n\n  # Bind9Instance status subresource (separate permissions for least privilege)\n  - apiGroups: [\"bindy.firestoned.io\"]\n    resources: [\"bind9instances/status\"]\n    verbs: [\"get\", \"update\", \"patch\"]\n    # Status updates only need get/update/patch, not create/delete\n\n  # Bind9Cluster resources\n  - apiGroups: [\"bindy.firestoned.io\"]\n    resources: [\"bind9clusters\"]\n    verbs: [\"get\", \"list\", \"watch\", \"create\", \"update\", \"patch\", \"delete\"]\n    # Permissions needed:\n    # - \"get\", \"list\", \"watch\": Read clusters for status updates\n    # - \"create\": Create clusters for ClusterBind9Provider\n    # - \"update\", \"patch\": Update cluster configuration\n    # - \"delete\": Clean up clusters (ClusterBind9Provider finalizer cleanup)\n\n  # Bind9Cluster status subresource (separate permissions for least privilege)\n  - apiGroups: [\"bindy.firestoned.io\"]\n    resources: [\"bind9clusters/status\"]\n    verbs: [\"get\", \"update\", \"patch\"]\n    # Status updates only need get/update/patch, not create/delete\n\n  # ClusterBind9Provider resources - cluster-scoped, NO DELETE (least privilege)\n  - apiGroups: [\"bindy.firestoned.io\"]\n    resources: [\"clusterbind9providers\"]\n    verbs: [\"get\", \"list\", \"watch\", \"create\", \"update\", \"patch\"]\n    # Removed: \"delete\" - Use bindy-admin-role for deletions\n\n  # ClusterBind9Provider status subresource (separate permissions for least privilege)\n  - apiGroups: [\"bindy.firestoned.io\"]\n    resources: [\"clusterbind9providers/status\"]\n    verbs: [\"get\", \"update\", \"patch\"]\n    # Status updates only need get/update/patch, not create/delete\n\n  # DNSZone resources - NO DELETE (least privilege)\n  - apiGroups: [\"bindy.firestoned.io\"]\n    resources: [\"dnszones\"]\n    verbs: [\"get\", \"list\", \"watch\", \"create\", \"update\", \"patch\"]\n    # Removed: \"delete\" - Use bindy-admin-role for deletions\n\n  # DNSZone status subresource (separate permissions for least privilege)\n  - apiGroups: [\"bindy.firestoned.io\"]\n    resources: [\"dnszones/status\"]\n    verbs: [\"get\", \"update\", \"patch\"]\n    # Status updates only need get/update/patch, not create/delete\n\n  # Record resources - NO DELETE (least privilege)\n  - apiGroups: [\"bindy.firestoned.io\"]\n    resources:\n      - \"arecords\"\n      - \"aaaarecords\"\n      - \"txtrecords\"\n      - \"cnamerecords\"\n      - \"mxrecords\"\n      - \"nsrecords\"\n      - \"srvrecords\"\n      - \"caarecords\"\n    verbs: [\"get\", \"list\", \"watch\", \"create\", \"update\", \"patch\"]\n    # Removed: \"delete\" - Use bindy-admin-role for deletions\n\n  # Record status subresources (separate permissions for least privilege)\n  - apiGroups: [\"bindy.firestoned.io\"]\n    resources:\n      - \"arecords/status\"\n      - \"aaaarecords/status\"\n      - \"txtrecords/status\"\n      - \"cnamerecords/status\"\n      - \"mxrecords/status\"\n      - \"nsrecords/status\"\n      - \"srvrecords/status\"\n      - \"caarecords/status\"\n    verbs: [\"get\", \"update\", \"patch\"]\n    # Status updates only need get/update/patch, not create/delete\n\n  # Kubernetes Deployments\n  - apiGroups: [\"apps\"]\n    resources: [\"deployments\"]\n    verbs: [\"get\", \"list\", \"watch\", \"create\", \"update\", \"patch\", \"delete\"]\n    # Permissions needed:\n    # - \"get\", \"list\", \"watch\": Read deployment status\n    # - \"create\": Create deployments for Bind9Instance\n    # - \"update\", \"patch\": Update deployment configuration\n    # - \"delete\": Finalizer cleanup (Bind9Instance reconciler)\n    # Note: Owner references provide automatic GC, but finalizer explicitly deletes\n\n  # Kubernetes Services\n  # trivy:ignore:KSV-0056\n  # Suppression Justification (KSV-0056 - Services/Endpoints Access):\n  #   REQUIRED FOR CORE FUNCTIONALITY - DNS operator MUST manage Services to expose BIND9 servers.\n  #   Mitigation Strategy:\n  #     1. Namespace-scoped via RoleBinding - cannot intercept traffic in other namespaces\n  #     2. Owner references - Services are bound to Bind9Instance resources (automatic cleanup)\n  #     3. Finalizers - Explicit deletion only when parent Bind9Instance is deleted\n  #     4. Service selectors - Only route traffic to pods owned by this operator\n  #     5. NetworkPolicy enforcement - Traffic interception prevented by cluster NetworkPolicies\n  #   Risk Acceptance: Service management is fundamental to DNS server operation. Network policies\n  #                    and namespace isolation provide defense-in-depth against traffic interception.\n  #   Compliance: NIST SP 800-190 (container orchestration security), CIS Kubernetes Benchmark 5.1.5\n  - apiGroups: [\"\"]\n    resources: [\"services\"]\n    verbs: [\"get\", \"list\", \"watch\", \"create\", \"update\", \"patch\", \"delete\"]\n    # Permissions needed:\n    # - \"get\", \"list\", \"watch\": Read service status and endpoints\n    # - \"create\": Create services for Bind9Instance\n    # - \"update\", \"patch\": Update service configuration (preserves clusterIP)\n    # - \"delete\": Finalizer cleanup (Bind9Instance reconciler)\n    # Note: Owner references provide automatic GC, but finalizer explicitly deletes\n\n  # Kubernetes ConfigMaps\n  - apiGroups: [\"\"]\n    resources: [\"configmaps\"]\n    verbs: [\"get\", \"list\", \"watch\", \"create\", \"update\", \"patch\", \"delete\"]\n    # Permissions needed:\n    # - \"get\", \"list\", \"watch\": Read configuration data\n    # - \"create\": Create ConfigMaps for Bind9Instance configuration\n    # - \"update\", \"patch\": Update BIND9 configuration (zone changes)\n    # - \"delete\": Finalizer cleanup (Bind9Instance reconciler)\n    # Note: Owner references provide automatic GC, but finalizer explicitly deletes\n\n  # Kubernetes Secrets - RNDC key management (CRITICAL: least privilege for sensitive data)\n  # trivy:ignore:KSV-0041\n  # Suppression Justification (KSV-0041 - Secrets Access):\n  #   REQUIRED FOR CORE FUNCTIONALITY - DNS operator MUST read RNDC secrets across the\n  #   namespaces it watches for BIND9 authentication.\n  #   B-5 hardening (2026-06-09): cluster-wide access is now READ-ONLY. The mutating verbs\n  #   (create/update/patch/delete) have been moved out of this ClusterRole into the\n  #   namespaced Role `bindy-secrets-writer` (see secrets-role.yaml), bound only in the\n  #   operator namespace. This removes cluster-wide Secret WRITE \u{2014} a compromised operator\n  #   can no longer create, modify, or delete Secrets in other namespaces (e.g. kube-system).\n  #   For multi-namespace deployments, replicate the `bindy-secrets-writer` Role/RoleBinding\n  #   into each target namespace.\n  #   Mitigation Strategy:\n  #     1. Read-only cluster-wide; write verbs namespaced to the operator namespace only\n  #     2. Purpose-specific secrets - only manages secrets with the \"-rndc-key\" suffix\n  #     3. Audit logging enabled - all secret operations logged for compliance (PCI-DSS 10.2)\n  #     4. RBAC separation - admin role required for cluster-wide destructive secret access\n  #   Risk Acceptance: Cluster-wide Secret READ is required by the controller\'s owned-Secret\n  #     watch (`.owns(Api::<Secret>::all)`), which RBAC cannot filter by name/label.\n  #   Compliance: PCI-DSS 7.1.2 (minimal permissions), NIST SP 800-190 (container secrets management)\n  - apiGroups: [\"\"]\n    resources: [\"secrets\"]\n    verbs: [\"get\", \"list\", \"watch\"]\n    # Cluster-wide, READ-ONLY:\n    # - \"get\": Load RNDC keys for zone updates (DNSZone reconciler)\n    # - \"list\": Check if RNDC secrets exist (Bind9Cluster reconciler)\n    # - \"watch\": Monitor RNDC secret changes (Bind9Instance .owns(Secret) watch)\n    # Mutating verbs (create/update/patch/delete) live in the namespaced\n    # bindy-secrets-writer Role (secrets-role.yaml) \u{2014} operator namespace only.\n\n  # Kubernetes ServiceAccounts\n  - apiGroups: [\"\"]\n    resources: [\"serviceaccounts\"]\n    verbs: [\"get\", \"list\", \"watch\", \"create\", \"update\", \"patch\", \"delete\"]\n    # Permissions needed:\n    # - \"get\", \"list\", \"watch\": Read service account status\n    # - \"create\": Create service accounts for Bind9Instance pods\n    # - \"update\", \"patch\": Update service account configuration\n    # - \"delete\": Finalizer cleanup (Bind9Instance reconciler)\n    # Note: Owner references provide automatic GC, but finalizer explicitly deletes\n\n  # Kubernetes Pods - READ-ONLY (for discovery and status)\n  - apiGroups: [\"\"]\n    resources: [\"pods\"]\n    verbs: [\"get\", \"list\", \"watch\"]\n\n  # Kubernetes Endpoints - READ-ONLY (for service discovery)\n  - apiGroups: [\"\"]\n    resources: [\"endpoints\"]\n    verbs: [\"get\", \"list\", \"watch\"]\n\n  # Events for logging (no delete needed)\n  - apiGroups: [\"\"]\n    resources: [\"events\"]\n    verbs: [\"create\", \"patch\"]\n\n  # Leases for leader election (no delete needed for HA)\n  - apiGroups: [\"coordination.k8s.io\"]\n    resources: [\"leases\"]\n    verbs: [\"get\", \"create\", \"update\", \"patch\"]\n";
Expand description

Embedded RBAC YAML files — compiled into the binary so bootstrap is self-contained.