istio.io/istio@v0.0.0-20240520182934-d79c90f27776/samples/security/spire/spire-quickstart.yaml (about) 1 --- 2 apiVersion: v1 3 kind: Namespace 4 metadata: 5 name: spire 6 7 --- 8 apiVersion: storage.k8s.io/v1 9 kind: CSIDriver 10 metadata: 11 name: "csi.spiffe.io" 12 spec: 13 # Only ephemeral, inline volumes are supported. There is no need for a 14 # controller to provision and attach volumes. 15 attachRequired: false 16 17 # Request the pod information which the CSI driver uses to verify that an 18 # ephemeral mount was requested. 19 podInfoOnMount: true 20 21 # Don't change ownership on the contents of the mount since the Workload API 22 # Unix Domain Socket is typically open to all (i.e. 0777). 23 fsGroupPolicy: None 24 25 # Declare support for ephemeral volumes only. 26 volumeLifecycleModes: 27 - Ephemeral 28 29 --- 30 apiVersion: v1 31 kind: ServiceAccount 32 metadata: 33 name: spire-server 34 namespace: spire 35 36 --- 37 # ConfigMap for spire-agent bootstrapping. 38 apiVersion: v1 39 kind: ConfigMap 40 metadata: 41 name: spire-bundle 42 namespace: spire 43 44 --- 45 # ClusterRole to allow spire-server to query k8s API server. 46 kind: ClusterRole 47 apiVersion: rbac.authorization.k8s.io/v1 48 metadata: 49 name: spire-server-cluster-role 50 rules: 51 # allow TokenReview requests (to verify service account tokens for PSAT 52 # attestation) 53 - apiGroups: ["authentication.k8s.io"] 54 resources: ["tokenreviews"] 55 verbs: ["get", "create"] 56 - apiGroups: [""] 57 resources: ["nodes"] 58 verbs: ["get"] 59 60 --- 61 # Binds above cluster role to spire-server service account. 62 kind: ClusterRoleBinding 63 apiVersion: rbac.authorization.k8s.io/v1 64 metadata: 65 name: spire-server-cluster-role-binding 66 subjects: 67 - kind: ServiceAccount 68 name: spire-server 69 namespace: spire 70 roleRef: 71 kind: ClusterRole 72 name: spire-server-cluster-role 73 apiGroup: rbac.authorization.k8s.io 74 75 --- 76 # Role for the SPIRE server. 77 kind: Role 78 apiVersion: rbac.authorization.k8s.io/v1 79 metadata: 80 namespace: spire 81 name: spire-server-role 82 rules: 83 # allow "get" access to pods (to resolve selectors for PSAT attestation) 84 - apiGroups: [""] 85 resources: ["pods"] 86 verbs: ["get"] 87 # allow access to "get" and "patch" the spire-bundle ConfigMap (for SPIRE 88 # agent bootstrapping, see the spire-bundle ConfigMap) 89 - apiGroups: [""] 90 resources: ["configmaps"] 91 resourceNames: ["spire-bundle"] 92 verbs: ["get", "patch"] 93 94 --- 95 # RoleBinding granting the spire-server-role to the SPIRE server 96 # service account. 97 kind: RoleBinding 98 apiVersion: rbac.authorization.k8s.io/v1 99 metadata: 100 name: spire-server-role-binding 101 namespace: spire 102 subjects: 103 - kind: ServiceAccount 104 name: spire-server 105 namespace: spire 106 roleRef: 107 kind: Role 108 name: spire-server-role 109 apiGroup: rbac.authorization.k8s.io 110 111 --- 112 # ClusterRules for the SPIRE Controller Manager. 113 apiVersion: rbac.authorization.k8s.io/v1 114 kind: ClusterRole 115 metadata: 116 name: manager-role 117 rules: 118 - apiGroups: [""] 119 resources: ["namespaces"] 120 verbs: ["get", "list", "watch"] 121 - apiGroups: ["admissionregistration.k8s.io"] 122 resources: ["validatingwebhookconfigurations"] 123 verbs: ["get", "list", "patch", "watch"] 124 - apiGroups: [""] 125 resources: ["nodes"] 126 verbs: ["get", "list", "watch"] 127 - apiGroups: [""] 128 resources: ["pods"] 129 verbs: ["get", "list", "watch"] 130 - apiGroups: ["spire.spiffe.io"] 131 resources: ["clusterfederatedtrustdomains"] 132 verbs: ["get", "list", "watch", "create", "update", "patch", "delete"] 133 - apiGroups: ["spire.spiffe.io"] 134 resources: ["clusterfederatedtrustdomains/finalizers"] 135 verbs: ["update"] 136 - apiGroups: ["spire.spiffe.io"] 137 resources: ["clusterfederatedtrustdomains/status"] 138 verbs: ["get", "patch", "update"] 139 - apiGroups: ["spire.spiffe.io"] 140 resources: ["clusterspiffeids"] 141 verbs: ["get", "list", "watch", "create", "update", "patch", "delete"] 142 - apiGroups: ["spire.spiffe.io"] 143 resources: ["clusterspiffeids/finalizers"] 144 verbs: ["update"] 145 - apiGroups: ["spire.spiffe.io"] 146 resources: ["clusterspiffeids/status"] 147 verbs: ["get", "patch", "update"] 148 149 --- 150 # Binds manager-role cluster role to spire-server service account. 151 apiVersion: rbac.authorization.k8s.io/v1 152 kind: ClusterRoleBinding 153 metadata: 154 name: manager-role-binding 155 roleRef: 156 apiGroup: rbac.authorization.k8s.io 157 kind: ClusterRole 158 name: manager-role 159 subjects: 160 - kind: ServiceAccount 161 name: spire-server 162 namespace: spire 163 164 --- 165 # Permissions for the SPIRE server to do leader election. 166 apiVersion: rbac.authorization.k8s.io/v1 167 kind: Role 168 metadata: 169 name: leader-election-role 170 namespace: spire 171 rules: 172 - apiGroups: [""] 173 resources: ["configmaps"] 174 verbs: ["get", "list", "watch", "create", "update", "patch", "delete"] 175 - apiGroups: ["coordination.k8s.io"] 176 resources: ["leases"] 177 verbs: ["get", "list", "watch", "create", "update", "patch", "delete"] 178 - apiGroups: [""] 179 resources: ["events"] 180 verbs: ["create", "patch"] 181 182 --- 183 # Binds leader-election-role to spire-server service account. 184 apiVersion: rbac.authorization.k8s.io/v1 185 kind: RoleBinding 186 metadata: 187 name: leader-election-role-binding 188 namespace: spire 189 roleRef: 190 apiGroup: rbac.authorization.k8s.io 191 kind: Role 192 name: leader-election-role 193 subjects: 194 - kind: ServiceAccount 195 name: spire-server 196 namespace: spire 197 198 --- 199 # ConfigMap containing the SPIRE server configuration. 200 apiVersion: v1 201 kind: ConfigMap 202 metadata: 203 name: spire-server 204 namespace: spire 205 data: 206 server.conf: | 207 server { 208 bind_address = "0.0.0.0" 209 bind_port = "8081" 210 trust_domain = "example.org" 211 data_dir = "/run/spire/server/data" 212 log_level = "DEBUG" 213 federation { 214 bundle_endpoint { 215 address = "0.0.0.0" 216 port = 8443 217 } 218 } 219 } 220 221 plugins { 222 DataStore "sql" { 223 plugin_data { 224 database_type = "sqlite3" 225 connection_string = "/run/spire/server/data/datastore.sqlite3" 226 } 227 } 228 229 NodeAttestor "k8s_psat" { 230 plugin_data { 231 clusters = { 232 # NOTE: Change this to your cluster name 233 "demo-cluster" = { 234 service_account_allow_list = ["spire:spire-agent"] 235 } 236 } 237 } 238 } 239 240 KeyManager "disk" { 241 plugin_data { 242 keys_path = "/run/spire/server/data/keys.json" 243 } 244 } 245 246 Notifier "k8sbundle" { 247 plugin_data { 248 namespace = "spire" 249 } 250 } 251 } 252 253 health_checks { 254 listener_enabled = true 255 bind_address = "0.0.0.0" 256 bind_port = "8080" 257 live_path = "/live" 258 ready_path = "/ready" 259 } 260 261 --- 262 # Configuration for the SPIRE Controller Manager. 263 apiVersion: v1 264 kind: ConfigMap 265 metadata: 266 name: spire-controller-manager-config 267 namespace: spire 268 data: 269 spire-controller-manager-config.yaml: | 270 apiVersion: spire.spiffe.io/v1alpha1 271 kind: ControllerManagerConfig 272 metrics: 273 bindAddress: 127.0.0.1:8082 274 healthProbe: 275 bindAddress: 127.0.0.1:8083 276 leaderElection: 277 leaderElect: true 278 resourceName: 98c9c988.spiffe.io 279 resourceNamespace: spire 280 clusterName: demo-cluster 281 trustDomain: example.org 282 ignoreNamespaces: 283 - kube-system 284 - kube-public 285 - spire 286 - local-path-storage 287 288 --- 289 # SPIRE Server Deployment. 290 apiVersion: apps/v1 291 kind: Deployment 292 metadata: 293 name: spire-server 294 namespace: spire 295 labels: 296 app: spire-server 297 spec: 298 replicas: 1 299 selector: 300 matchLabels: 301 app: spire-server 302 template: 303 metadata: 304 namespace: spire 305 labels: 306 app: spire-server 307 spec: 308 serviceAccountName: spire-server 309 shareProcessNamespace: true 310 containers: 311 - name: spire-server 312 image: ghcr.io/spiffe/spire-server:1.5.4 313 imagePullPolicy: IfNotPresent 314 args: 315 - -config 316 - /run/spire/server/config/server.conf 317 livenessProbe: 318 httpGet: 319 path: /live 320 port: 8080 321 failureThreshold: 2 322 initialDelaySeconds: 15 323 periodSeconds: 60 324 timeoutSeconds: 3 325 readinessProbe: 326 httpGet: 327 path: /ready 328 port: 8080 329 initialDelaySeconds: 5 330 periodSeconds: 5 331 ports: 332 - containerPort: 8081 333 volumeMounts: 334 - name: spire-config 335 mountPath: /run/spire/server/config 336 readOnly: true 337 - name: spire-server-socket 338 mountPath: /tmp/spire-server/private 339 readOnly: false 340 - name: spire-controller-manager 341 image: ghcr.io/spiffe/spire-controller-manager:0.2.3 342 imagePullPolicy: IfNotPresent 343 args: 344 - "--config=spire-controller-manager-config.yaml" 345 ports: 346 - containerPort: 9443 347 volumeMounts: 348 - name: spire-server-socket 349 mountPath: /spire-server 350 readOnly: true 351 - name: spire-controller-manager-config 352 mountPath: /spire-controller-manager-config.yaml 353 subPath: spire-controller-manager-config.yaml 354 volumes: 355 - name: spire-config 356 configMap: 357 name: spire-server 358 - name: spire-server-socket 359 emptyDir: {} 360 - name: spire-controller-manager-config 361 configMap: 362 name: spire-controller-manager-config 363 364 --- 365 # Service definition for SPIRE server defining the gRPC port. 366 apiVersion: v1 367 kind: Service 368 metadata: 369 name: spire-server 370 namespace: spire 371 spec: 372 type: NodePort 373 ports: 374 - name: grpc 375 port: 8081 376 targetPort: 8081 377 protocol: TCP 378 selector: 379 app: spire-server 380 381 --- 382 # Service definition for SPIRE server bundle endpoint. 383 apiVersion: v1 384 kind: Service 385 metadata: 386 name: spire-server-bundle-endpoint 387 namespace: spire 388 spec: 389 type: NodePort 390 ports: 391 - name: tcp-api 392 port: 8443 393 protocol: TCP 394 selector: 395 app: spire-server 396 397 --- 398 # Service definition for SPIRE controller manager webhook. 399 apiVersion: v1 400 kind: Service 401 metadata: 402 name: spire-controller-manager-webhook-service 403 namespace: spire 404 spec: 405 ports: 406 - name: tcp 407 port: 443 408 protocol: TCP 409 targetPort: 9443 410 selector: 411 app: spire-server 412 413 --- 414 # ClusterFederatedTrustDomains CRD. 415 apiVersion: apiextensions.k8s.io/v1 416 kind: CustomResourceDefinition 417 metadata: 418 annotations: 419 controller-gen.kubebuilder.io/version: v0.8.0 420 creationTimestamp: null 421 name: clusterfederatedtrustdomains.spire.spiffe.io 422 spec: 423 group: spire.spiffe.io 424 names: 425 kind: ClusterFederatedTrustDomain 426 listKind: ClusterFederatedTrustDomainList 427 plural: clusterfederatedtrustdomains 428 singular: clusterfederatedtrustdomain 429 scope: Cluster 430 versions: 431 - additionalPrinterColumns: 432 - jsonPath: .spec.trustDomain 433 name: Trust Domain 434 type: string 435 - jsonPath: .spec.bundleEndpointURL 436 name: Endpoint URL 437 type: string 438 name: v1alpha1 439 schema: 440 openAPIV3Schema: 441 description: ClusterFederatedTrustDomain is the Schema for the clusterfederatedtrustdomains 442 API 443 properties: 444 apiVersion: 445 description: 'APIVersion defines the versioned schema of this representation 446 of an object. Servers should convert recognized schemas to the latest 447 internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' 448 type: string 449 kind: 450 description: 'Kind is a string value representing the REST resource this 451 object represents. Servers may infer this from the endpoint the client 452 submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' 453 type: string 454 metadata: 455 type: object 456 spec: 457 description: ClusterFederatedTrustDomainSpec defines the desired state 458 of ClusterFederatedTrustDomain 459 properties: 460 bundleEndpointProfile: 461 description: BundleEndpointProfile is the profile for the bundle endpoint. 462 properties: 463 endpointSPIFFEID: 464 description: EndpointSPIFFEID is the SPIFFE ID of the bundle endpoint. 465 It is required for the "https_spiffe" profile. 466 type: string 467 type: 468 description: Type is the type of the bundle endpoint profile. 469 enum: 470 - https_spiffe 471 - https_web 472 type: string 473 required: 474 - type 475 type: object 476 bundleEndpointURL: 477 description: BundleEndpointURL is the URL of the bundle endpoint. 478 It must be an HTTPS URL and cannot contain userinfo (i.e. username/password). 479 type: string 480 trustDomain: 481 description: TrustDomain is the name of the trust domain to federate 482 with (e.g. example.org) 483 pattern: '[a-z0-9._-]{1,255}' 484 type: string 485 trustDomainBundle: 486 description: TrustDomainBundle is the contents of the bundle for the 487 referenced trust domain. This field is optional when the resource 488 is created. 489 type: string 490 required: 491 - bundleEndpointProfile 492 - bundleEndpointURL 493 - trustDomain 494 type: object 495 status: 496 description: ClusterFederatedTrustDomainStatus defines the observed state 497 of ClusterFederatedTrustDomain 498 type: object 499 type: object 500 served: true 501 storage: true 502 subresources: 503 status: {} 504 status: 505 acceptedNames: 506 kind: "" 507 plural: "" 508 conditions: [] 509 storedVersions: [] 510 511 --- 512 # ClusterSPIFFEID CRD. 513 apiVersion: apiextensions.k8s.io/v1 514 kind: CustomResourceDefinition 515 metadata: 516 annotations: 517 controller-gen.kubebuilder.io/version: v0.8.0 518 creationTimestamp: null 519 name: clusterspiffeids.spire.spiffe.io 520 spec: 521 group: spire.spiffe.io 522 names: 523 kind: ClusterSPIFFEID 524 listKind: ClusterSPIFFEIDList 525 plural: clusterspiffeids 526 singular: clusterspiffeid 527 scope: Cluster 528 versions: 529 - name: v1alpha1 530 schema: 531 openAPIV3Schema: 532 description: ClusterSPIFFEID is the Schema for the clusterspiffeids API 533 properties: 534 apiVersion: 535 description: 'APIVersion defines the versioned schema of this representation 536 of an object. Servers should convert recognized schemas to the latest 537 internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' 538 type: string 539 kind: 540 description: 'Kind is a string value representing the REST resource this 541 object represents. Servers may infer this from the endpoint the client 542 submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' 543 type: string 544 metadata: 545 type: object 546 spec: 547 description: ClusterSPIFFEIDSpec defines the desired state of ClusterSPIFFEID 548 properties: 549 admin: 550 description: Admin indicates whether or not the SVID can be used to 551 access the SPIRE administrative APIs. Extra care should be taken 552 to only apply this SPIFFE ID to admin workloads. 553 type: boolean 554 dnsNameTemplates: 555 description: DNSNameTemplate represents templates for extra DNS names 556 that are applicable to SVIDs minted for this ClusterSPIFFEID. The 557 node and pod spec are made available to the template under .NodeSpec, 558 .PodSpec respectively. 559 items: 560 type: string 561 type: array 562 downstream: 563 description: Downstream indicates that the entry describes a downstream SPIRE server. 564 type: boolean 565 federatesWith: 566 description: FederatesWith is a list of trust domain names that workloads 567 that obtain this SPIFFE ID will federate with. 568 items: 569 type: string 570 type: array 571 namespaceSelector: 572 description: NamespaceSelector selects the namespaces that are targeted 573 by this CRD. 574 properties: 575 matchExpressions: 576 description: matchExpressions is a list of label selector requirements. 577 The requirements are ANDed. 578 items: 579 description: A label selector requirement is a selector that 580 contains values, a key, and an operator that relates the key 581 and values. 582 properties: 583 key: 584 description: key is the label key that the selector applies 585 to. 586 type: string 587 operator: 588 description: operator represents a key's relationship to 589 a set of values. Valid operators are In, NotIn, Exists 590 and DoesNotExist. 591 type: string 592 values: 593 description: values is an array of string values. If the 594 operator is In or NotIn, the values array must be non-empty. 595 If the operator is Exists or DoesNotExist, the values 596 array must be empty. This array is replaced during a strategic 597 merge patch. 598 items: 599 type: string 600 type: array 601 required: 602 - key 603 - operator 604 type: object 605 type: array 606 matchLabels: 607 additionalProperties: 608 type: string 609 description: matchLabels is a map of {key,value} pairs. A single 610 {key,value} in the matchLabels map is equivalent to an element 611 of matchExpressions, whose key field is "key", the operator 612 is "In", and the values array contains only "value". The requirements 613 are ANDed. 614 type: object 615 type: object 616 podSelector: 617 description: PodSelector selects the pods that are targeted by this 618 CRD. 619 properties: 620 matchExpressions: 621 description: matchExpressions is a list of label selector requirements. 622 The requirements are ANDed. 623 items: 624 description: A label selector requirement is a selector that 625 contains values, a key, and an operator that relates the key 626 and values. 627 properties: 628 key: 629 description: key is the label key that the selector applies 630 to. 631 type: string 632 operator: 633 description: operator represents a key's relationship to 634 a set of values. Valid operators are In, NotIn, Exists 635 and DoesNotExist. 636 type: string 637 values: 638 description: values is an array of string values. If the 639 operator is In or NotIn, the values array must be non-empty. 640 If the operator is Exists or DoesNotExist, the values 641 array must be empty. This array is replaced during a strategic 642 merge patch. 643 items: 644 type: string 645 type: array 646 required: 647 - key 648 - operator 649 type: object 650 type: array 651 matchLabels: 652 additionalProperties: 653 type: string 654 description: matchLabels is a map of {key,value} pairs. A single 655 {key,value} in the matchLabels map is equivalent to an element 656 of matchExpressions, whose key field is "key", the operator 657 is "In", and the values array contains only "value". The requirements 658 are ANDed. 659 type: object 660 type: object 661 spiffeIDTemplate: 662 description: SPIFFEID is the SPIFFE ID template. The node and pod 663 spec are made available to the template under .NodeSpec, .PodSpec 664 respectively. 665 type: string 666 ttl: 667 description: TTL indicates an upper-bound time-to-live for SVIDs minted 668 for this ClusterSPIFFEID. If unset, a default will be chosen. 669 type: string 670 workloadSelectorTemplates: 671 description: WorkloadSelectorTemplates are templates to produce arbitrary 672 workload selectors that apply to a given workload before it will 673 receive this SPIFFE ID. The rendered value is interpreted by SPIRE 674 and are of the form type:value, where the value may, and often does, 675 contain semicolons, .e.g., k8s:container-image:docker/hello-world 676 The node and pod spec are made available to the template under .NodeSpec, 677 .PodSpec respectively. 678 items: 679 type: string 680 type: array 681 required: 682 - spiffeIDTemplate 683 type: object 684 status: 685 description: ClusterSPIFFEIDStatus defines the observed state of ClusterSPIFFEID 686 properties: 687 stats: 688 description: Stats produced by the last entry reconciliation run 689 properties: 690 entriesMasked: 691 description: How many entries were masked by entries for other 692 ClusterSPIFFEIDs. This happens when one or more ClusterSPIFFEIDs 693 produce an entry for the same pod with the same set of workload 694 selectors. 695 type: integer 696 entriesToSet: 697 description: How many entries are to be set for this ClusterSPIFFEID. 698 In nominal conditions, this should reflect the number of pods 699 selected, but not always if there were problems encountered 700 rendering an entry for the pod (RenderFailures) or entries are 701 masked (EntriesMasked). 702 type: integer 703 entryFailures: 704 description: How many entries were unable to be set due to failures 705 to create or update the entries via the SPIRE Server API. 706 type: integer 707 namespacesIgnored: 708 description: How many (selected) namespaces were ignored (based 709 on configuration). 710 type: integer 711 namespacesSelected: 712 description: How many namespaces were selected. 713 type: integer 714 podEntryRenderFailures: 715 description: How many failures were encountered rendering an entry 716 selected pods. This could be due to either a bad template in 717 the ClusterSPIFFEID or Pod metadata that when applied to the 718 template did not produce valid entry values. 719 type: integer 720 podsSelected: 721 description: How many pods were selected out of the namespaces. 722 type: integer 723 type: object 724 type: object 725 type: object 726 served: true 727 storage: true 728 subresources: 729 status: {} 730 status: 731 acceptedNames: 732 kind: "" 733 plural: "" 734 conditions: [] 735 storedVersions: [] 736 737 --- 738 # ValidatingWebhookConfiguration for validating ClusterSPIFFEID and 739 # ClusterFederatedTrustDomain custom resources. 740 apiVersion: admissionregistration.k8s.io/v1 741 kind: ValidatingWebhookConfiguration 742 metadata: 743 name: spire-controller-manager-webhook 744 webhooks: 745 - admissionReviewVersions: ["v1"] 746 clientConfig: 747 service: 748 name: spire-controller-manager-webhook-service 749 namespace: spire 750 path: /validate-spire-spiffe-io-v1alpha1-clusterfederatedtrustdomain 751 failurePolicy: Fail 752 name: vclusterfederatedtrustdomain.kb.io 753 rules: 754 - apiGroups: ["spire.spiffe.io"] 755 apiVersions: ["v1alpha1"] 756 operations: ["CREATE", "UPDATE"] 757 resources: ["clusterfederatedtrustdomains"] 758 sideEffects: None 759 - admissionReviewVersions: ["v1"] 760 clientConfig: 761 service: 762 name: spire-controller-manager-webhook-service 763 namespace: spire 764 path: /validate-spire-spiffe-io-v1alpha1-clusterspiffeid 765 failurePolicy: Fail 766 name: vclusterspiffeid.kb.io 767 rules: 768 - apiGroups: ["spire.spiffe.io"] 769 apiVersions: ["v1alpha1"] 770 operations: ["CREATE", "UPDATE"] 771 resources: ["clusterspiffeids"] 772 sideEffects: None 773 774 --- 775 apiVersion: v1 776 kind: ServiceAccount 777 metadata: 778 name: spire-agent 779 namespace: spire 780 781 --- 782 # Required cluster role to allow spire-agent to query k8s API server. 783 kind: ClusterRole 784 apiVersion: rbac.authorization.k8s.io/v1 785 metadata: 786 name: spire-agent-cluster-role 787 rules: 788 - apiGroups: [""] 789 resources: ["pods","nodes","nodes/proxy"] 790 verbs: ["get"] 791 792 --- 793 # Binds above cluster role to spire-agent service account. 794 kind: ClusterRoleBinding 795 apiVersion: rbac.authorization.k8s.io/v1 796 metadata: 797 name: spire-agent-cluster-role-binding 798 subjects: 799 - kind: ServiceAccount 800 name: spire-agent 801 namespace: spire 802 roleRef: 803 kind: ClusterRole 804 name: spire-agent-cluster-role 805 apiGroup: rbac.authorization.k8s.io 806 807 --- 808 # ConfigMap for the SPIRE agent featuring: 809 # 1) PSAT node attestation 810 # 2) K8S Workload Attestation over the secure kubelet port 811 apiVersion: v1 812 kind: ConfigMap 813 metadata: 814 name: spire-agent 815 namespace: spire 816 data: 817 agent.conf: | 818 agent { 819 data_dir = "/run/spire" 820 log_level = "DEBUG" 821 server_address = "spire-server" 822 server_port = "8081" 823 socket_path = "/run/secrets/workload-spiffe-uds/socket" 824 trust_bundle_path = "/run/spire/bundle/bundle.crt" 825 trust_domain = "example.org" 826 } 827 828 plugins { 829 NodeAttestor "k8s_psat" { 830 plugin_data { 831 # NOTE: Change this to your cluster name 832 cluster = "demo-cluster" 833 } 834 } 835 836 KeyManager "memory" { 837 plugin_data { 838 } 839 } 840 841 WorkloadAttestor "k8s" { 842 plugin_data { 843 # Defaults to the secure kubelet port by default. 844 # Minikube does not have a cert in the cluster CA bundle that 845 # can authenticate the kubelet cert, so skip validation. 846 skip_kubelet_verification = true 847 848 # We need to set disable_container_selectors = true if we make holdApplicationUntilProxyStarts = true in istio 849 # see https://istio.io/latest/docs/reference/config/istio.mesh.v1alpha1/#ProxyConfig 850 # If true, container selectors are not produced. 851 # This can be used to produce pod selectors when the workload pod is known 852 # but the workload container is not ready at the time of attestation. 853 # disable_container_selectors = true 854 } 855 } 856 857 WorkloadAttestor "unix" { 858 plugin_data { 859 } 860 } 861 862 } 863 864 --- 865 # SPIRE Agent DaemonSet. 866 apiVersion: apps/v1 867 kind: DaemonSet 868 metadata: 869 name: spire-agent 870 namespace: spire 871 labels: 872 app: spire-agent 873 spec: 874 selector: 875 matchLabels: 876 app: spire-agent 877 template: 878 metadata: 879 namespace: spire 880 labels: 881 app: spire-agent 882 spec: 883 hostPID: true 884 hostNetwork: true 885 dnsPolicy: ClusterFirstWithHostNet 886 serviceAccountName: spire-agent 887 containers: 888 - name: spire-agent 889 image: ghcr.io/spiffe/spire-agent:1.5.4 890 imagePullPolicy: IfNotPresent 891 args: ["-config", "/run/spire/config/agent.conf"] 892 volumeMounts: 893 - name: spire-config 894 mountPath: /run/spire/config 895 readOnly: true 896 - name: spire-bundle 897 mountPath: /run/spire/bundle 898 readOnly: true 899 - name: spire-agent-socket-dir 900 mountPath: /run/secrets/workload-spiffe-uds 901 - name: spire-token 902 mountPath: /var/run/secrets/tokens 903 # This is the container which runs the SPIFFE CSI driver. 904 - name: spiffe-csi-driver 905 image: ghcr.io/spiffe/spiffe-csi-driver:0.2.0 906 imagePullPolicy: IfNotPresent 907 args: [ 908 "-workload-api-socket-dir", "/spire-agent-socket", 909 "-csi-socket-path", "/spiffe-csi/csi.sock", 910 ] 911 env: 912 # The CSI driver needs a unique node ID. The node name can be 913 # used for this purpose. 914 - name: MY_NODE_NAME 915 valueFrom: 916 fieldRef: 917 fieldPath: spec.nodeName 918 volumeMounts: 919 # The volume containing the SPIRE agent socket. The SPIFFE CSI 920 # driver will mount this directory into containers. 921 - mountPath: /spire-agent-socket 922 name: spire-agent-socket-dir 923 readOnly: true 924 # The volume that will contain the CSI driver socket shared 925 # with the kubelet and the driver registrar. 926 - mountPath: /spiffe-csi 927 name: spiffe-csi-socket-dir 928 # The volume containing mount points for containers. 929 - mountPath: /var/lib/kubelet/pods 930 mountPropagation: Bidirectional 931 name: mountpoint-dir 932 securityContext: 933 privileged: true 934 # This container runs the CSI Node Driver Registrar which takes care 935 # of all the little details required to register a CSI driver with 936 # the kubelet. 937 - name: node-driver-registrar 938 image: registry.k8s.io/sig-storage/csi-node-driver-registrar:v2.4.0 939 imagePullPolicy: IfNotPresent 940 args: [ 941 "-csi-address", "/spiffe-csi/csi.sock", 942 "-kubelet-registration-path", "/var/lib/kubelet/plugins/csi.spiffe.io/csi.sock", 943 ] 944 volumeMounts: 945 # The registrar needs access to the SPIFFE CSI driver socket 946 - mountPath: /spiffe-csi 947 name: spiffe-csi-socket-dir 948 # The registrar needs access to the Kubelet plugin registration 949 # directory 950 - name: kubelet-plugin-registration-dir 951 mountPath: /registration 952 volumes: 953 - name: spire-config 954 configMap: 955 name: spire-agent 956 - name: spire-bundle 957 configMap: 958 name: spire-bundle 959 - name: spire-token 960 projected: 961 sources: 962 - serviceAccountToken: 963 path: spire-agent 964 expirationSeconds: 7200 965 audience: spire-server 966 # This volume is used to share the workload api socket between the 967 # CSI driver and SPIRE agent 968 - name: spire-agent-socket-dir 969 emptyDir: {} 970 # This volume is where the socket for kubelet->driver communication lives 971 - name: spiffe-csi-socket-dir 972 hostPath: 973 path: /var/lib/kubelet/plugins/csi.spiffe.io 974 type: DirectoryOrCreate 975 # This volume is where the SPIFFE CSI driver mounts volumes 976 - name: mountpoint-dir 977 hostPath: 978 path: /var/lib/kubelet/pods 979 type: Directory 980 # This volume is where the node-driver-registrar registers the plugin 981 # with kubelet 982 - name: kubelet-plugin-registration-dir 983 hostPath: 984 path: /var/lib/kubelet/plugins_registry 985 type: Directory