From 28acde1401d74dc078c6daff1830e22d31f009e4 Mon Sep 17 00:00:00 2001 From: ivanauth Date: Tue, 25 Nov 2025 19:52:07 -0500 Subject: [PATCH] Document extraServiceAccountAnnotations with AWS IRSA example --- README.md | 83 +++++++- examples/aws-iam-service-account/README.md | 183 ++++++++++++++++++ .../kustomization.yaml | 5 + .../spicedb-with-iam-role.yaml | 121 ++++++++++++ 4 files changed, 391 insertions(+), 1 deletion(-) create mode 100644 examples/aws-iam-service-account/README.md create mode 100644 examples/aws-iam-service-account/kustomization.yaml create mode 100644 examples/aws-iam-service-account/spicedb-with-iam-role.yaml diff --git a/README.md b/README.md index 727d0cbc..ddfcc858 100644 --- a/README.md +++ b/README.md @@ -80,10 +80,91 @@ zed --insecure --endpoint=localhost:50051 --token=averysecretpresharedkey schema ## Where To Go From Here -- Check out the [examples](examples) directory to see how to configure `SpiceDBCluster` for production, including datastore backends, TLS, and Ingress. +- Check out the [examples](examples) directory to see how to configure `SpiceDBCluster` for production, including datastore backends, TLS, Ingress, and cloud provider integrations. - Learn how to use SpiceDB via the [docs](https://docs.authzed.com/) and [playground](https://play.authzed.com/). - Ask questions and join the community in [discord](https://authzed.com/discord). +## Configuration Options + +The `SpiceDBCluster` resource supports various configuration options through the `spec.config` field: + +### Service Account Annotations + +The `extraServiceAccountAnnotations` field allows you to add custom annotations to the ServiceAccount created for SpiceDB pods. This is particularly useful for cloud provider integrations that use workload identity. + +#### AWS IAM Roles for Service Accounts (IRSA) + +```yaml +apiVersion: authzed.com/v1alpha1 +kind: SpiceDBCluster +metadata: + name: spicedb-with-irsa +spec: + config: + datastoreEngine: postgres + # Required for RDS IAM authentication + datastoreCredentialsProviderName: "aws-iam" + extraServiceAccountAnnotations: + eks.amazonaws.com/role-arn: "arn:aws:iam::123456789012:role/spicedb-role" +``` + +See the [AWS IAM Service Account example](examples/aws-iam-service-account/) for a complete guide on using IRSA with SpiceDB. + +#### GCP Workload Identity + +```yaml +apiVersion: authzed.com/v1alpha1 +kind: SpiceDBCluster +metadata: + name: spicedb-with-workload-identity +spec: + config: + datastoreEngine: postgres + extraServiceAccountAnnotations: + iam.gke.io/gcp-service-account: "spicedb@my-project.iam.gserviceaccount.com" +``` + +#### Azure Workload Identity + +```yaml +apiVersion: authzed.com/v1alpha1 +kind: SpiceDBCluster +metadata: + name: spicedb-with-azure-wi +spec: + config: + datastoreEngine: postgres + extraServiceAccountAnnotations: + azure.workload.identity/client-id: "" +``` + +### Custom Service Account Name + +You can specify a custom service account name using the `serviceAccountName` field: + +```yaml +spec: + config: + serviceAccountName: "my-custom-spicedb-sa" + extraServiceAccountAnnotations: + eks.amazonaws.com/role-arn: "arn:aws:iam::123456789012:role/spicedb-role" +``` + +### Pod Labels and Annotations + +You can also add custom labels and annotations to SpiceDB pods: + +```yaml +spec: + config: + extraPodLabels: + environment: "production" + team: "platform" + extraPodAnnotations: + prometheus.io/scrape: "true" + prometheus.io/port: "9090" +``` + ## Automatic and Suggested Updates The SpiceDB operator now ships with a set of release channels for SpiceDB. diff --git a/examples/aws-iam-service-account/README.md b/examples/aws-iam-service-account/README.md new file mode 100644 index 00000000..f6830e01 --- /dev/null +++ b/examples/aws-iam-service-account/README.md @@ -0,0 +1,183 @@ +# AWS IAM Roles for Service Accounts (IRSA) with SpiceDB + +This example demonstrates how to configure SpiceDB to use AWS IAM Roles for Service Accounts (IRSA) on Amazon EKS clusters. + +## Overview + +IRSA allows Kubernetes pods to assume AWS IAM roles without storing long-lived AWS credentials. This is the recommended approach for granting AWS permissions to SpiceDB when running on EKS, as it: + +- Eliminates the need to store AWS credentials in secrets +- Provides automatic credential rotation +- Enables fine-grained access control per service account +- Follows AWS security best practices + +The `extraServiceAccountAnnotations` field in the SpiceDBCluster spec allows you to add annotations to the ServiceAccount created by the operator, which is required for IRSA to work. + +## Prerequisites + +1. **EKS Cluster with OIDC Provider**: Your EKS cluster must have an OIDC provider associated with it. + + ```bash + eksctl utils associate-iam-oidc-provider --cluster --approve + ``` + +2. **Create an IAM Role**: Create an IAM role with the necessary permissions (e.g., `rds-db:connect` for RDS IAM authentication). + +3. **Configure Trust Relationship**: Update the role's trust policy to allow the SpiceDB service account to assume it: + + ```json + { + "Version": "2012-10-17", + "Statement": [ + { + "Effect": "Allow", + "Principal": { + "Federated": "arn:aws:iam::123456789012:oidc-provider/oidc.eks.region.amazonaws.com/id/EXAMPLED539D4633E53DE1B716D3041E" + }, + "Action": "sts:AssumeRoleWithWebIdentity", + "Condition": { + "StringEquals": { + "oidc.eks.region.amazonaws.com/id/EXAMPLED539D4633E53DE1B716D3041E:sub": "system:serviceaccount:default:spicedb-with-irsa", + "oidc.eks.region.amazonaws.com/id/EXAMPLED539D4633E53DE1B716D3041E:aud": "sts.amazonaws.com" + } + } + } + ] + } + ``` + + > **Note**: The service account name in the trust policy (`spicedb-with-irsa`) must match the SpiceDBCluster name. If you use a custom `serviceAccountName` in your config, use that name instead. + +## Configuration + +### Basic IRSA Setup + +The key configuration is adding the `eks.amazonaws.com/role-arn` annotation to the service account: + +```yaml +apiVersion: authzed.com/v1alpha1 +kind: SpiceDBCluster +metadata: + name: spicedb-with-irsa +spec: + config: + datastoreEngine: postgres + extraServiceAccountAnnotations: + eks.amazonaws.com/role-arn: "arn:aws:iam::123456789012:role/your-iam-role" + secretName: spicedb-config +``` + +### Custom Service Account Name + +You can specify a custom service account name using the `serviceAccountName` field: + +```yaml +spec: + config: + serviceAccountName: "my-custom-sa" + extraServiceAccountAnnotations: + eks.amazonaws.com/role-arn: "arn:aws:iam::123456789012:role/your-iam-role" +``` + +> **Important**: If you use a custom service account name, update your IAM trust policy to reference `system:serviceaccount::`. + +## Use Case: RDS with IAM Authentication + +Instead of storing database passwords, you can use IAM authentication with RDS. This requires: + +1. The `eks.amazonaws.com/role-arn` annotation for IRSA +2. The `datastoreCredentialsProviderName` config set to `aws-iam` + +```yaml +apiVersion: authzed.com/v1alpha1 +kind: SpiceDBCluster +metadata: + name: spicedb-with-irsa + namespace: default +spec: + config: + datastoreEngine: postgres + # Enable AWS IAM credential provider for RDS authentication + datastoreCredentialsProviderName: "aws-iam" + extraServiceAccountAnnotations: + eks.amazonaws.com/role-arn: "arn:aws:iam::123456789012:role/spicedb-rds-role" + secretName: spicedb-config +--- +apiVersion: v1 +kind: Secret +metadata: + name: spicedb-config + namespace: default +stringData: + preshared_key: "your-very-secret-preshared-key" + # Note: No password in the URI - IAM authentication handles this + datastore_uri: "postgresql://spicedb_user@your-rds-endpoint.region.rds.amazonaws.com:5432/spicedb?sslmode=require" +``` + +### IAM Policy for RDS Access + +Your IAM role needs the `rds-db:connect` permission: + +```json +{ + "Version": "2012-10-17", + "Statement": [ + { + "Effect": "Allow", + "Action": "rds-db:connect", + "Resource": "arn:aws:rds-db:region:123456789012:dbuser:db-instance-resource-id/spicedb_user" + } + ] +} +``` + +## Deploying the Example + +1. Update the IAM role ARN in `spicedb-with-iam-role.yaml` with your actual role ARN +2. Update the RDS endpoint and database user in the secret +3. Apply the configuration: + + ```bash + kubectl apply -k . + ``` + +4. Verify the service account has the correct annotation: + + ```bash + kubectl get sa spicedb-with-irsa -o jsonpath='{.metadata.annotations}' + ``` + +## Troubleshooting + +1. **Check Service Account Annotations**: + + ```bash + kubectl get sa spicedb-with-irsa -o jsonpath='{.metadata.annotations}' + ``` + +2. **Verify Pod Has AWS Environment Variables**: + + ```bash + kubectl exec -it -- env | grep AWS + ``` + + You should see: + - `AWS_ROLE_ARN` + - `AWS_WEB_IDENTITY_TOKEN_FILE` + +3. **Check IAM Role Trust Policy**: Ensure the trust policy matches your cluster's OIDC provider and service account name (including namespace). + +4. **Verify RDS IAM Authentication is Enabled**: Ensure your RDS instance has IAM authentication enabled in the AWS console or via CLI. + +5. **Check SpiceDB Logs for Auth Errors**: + + ```bash + kubectl logs -l app.kubernetes.io/instance=spicedb-with-irsa + ``` + +## Additional Resources + +- [AWS Documentation on IRSA](https://docs.aws.amazon.com/eks/latest/userguide/iam-roles-for-service-accounts.html) +- [SpiceDB Operator Documentation](https://github.com/authzed/spicedb-operator) +- [Using IAM authentication with RDS](https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/UsingWithRDS.IAMDBAuth.html) +- [Creating an IAM policy for RDS IAM authentication](https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/UsingWithRDS.IAMDBAuth.IAMPolicy.html) diff --git a/examples/aws-iam-service-account/kustomization.yaml b/examples/aws-iam-service-account/kustomization.yaml new file mode 100644 index 00000000..61b5179e --- /dev/null +++ b/examples/aws-iam-service-account/kustomization.yaml @@ -0,0 +1,5 @@ +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization + +resources: + - spicedb-with-iam-role.yaml diff --git a/examples/aws-iam-service-account/spicedb-with-iam-role.yaml b/examples/aws-iam-service-account/spicedb-with-iam-role.yaml new file mode 100644 index 00000000..c4f901d6 --- /dev/null +++ b/examples/aws-iam-service-account/spicedb-with-iam-role.yaml @@ -0,0 +1,121 @@ +# Example: SpiceDB Cluster with AWS IAM Roles for Service Accounts (IRSA) +# +# This example demonstrates how to configure a SpiceDBCluster to use AWS IAM roles +# for service accounts, enabling SpiceDB pods to authenticate to RDS using IAM +# instead of storing database passwords. +# +# Prerequisites: +# 1. EKS cluster with OIDC provider enabled +# 2. IAM role created with trust policy for the service account +# 3. RDS instance with IAM authentication enabled +# 4. IAM policy granting rds-db:connect permission +# +# For more information about IRSA, see: +# https://docs.aws.amazon.com/eks/latest/userguide/iam-roles-for-service-accounts.html + +--- +apiVersion: authzed.com/v1alpha1 +kind: SpiceDBCluster +metadata: + name: spicedb-with-irsa + namespace: default +spec: + config: + # Configure the datastore (this example uses RDS PostgreSQL with IAM auth) + datastoreEngine: postgres + + # REQUIRED for RDS IAM Authentication: Enable the AWS IAM credentials provider + # This tells SpiceDB to use IAM authentication instead of password-based auth + datastoreCredentialsProviderName: "aws-iam" + + # The extraServiceAccountAnnotations field allows you to add annotations + # to the ServiceAccount created by the operator for SpiceDB pods. + # This annotation is essential for AWS IAM Roles for Service Accounts (IRSA). + extraServiceAccountAnnotations: + # This annotation tells EKS to associate the service account with an IAM role + # Replace the role ARN with your actual IAM role ARN + eks.amazonaws.com/role-arn: "arn:aws:iam::123456789012:role/spicedb-rds-access-role" + + # Optional: You can also add custom labels to the pods + extraPodLabels: + app.kubernetes.io/component: "authorization" + environment: "production" + + # Optional: You can add annotations to the pods as well + extraPodAnnotations: + prometheus.io/scrape: "true" + prometheus.io/port: "9090" + + secretName: spicedb-config + +--- +# Secret for SpiceDB configuration +# When using IRSA with RDS IAM authentication, you don't need to store passwords +apiVersion: v1 +kind: Secret +metadata: + name: spicedb-config + namespace: default +stringData: + # Required: preshared key for SpiceDB API authentication + preshared_key: "your-very-secret-preshared-key" + + # When using RDS with IAM authentication: + # - No password is needed in the URI + # - The database user must be configured for IAM auth in RDS + # - sslmode=require is recommended for security + datastore_uri: "postgresql://spicedb_user@your-rds-endpoint.region.rds.amazonaws.com:5432/spicedb?sslmode=require" + +--- +# Example: Using a custom service account name +# Use this if you need to control the service account name for IAM trust policy matching +apiVersion: authzed.com/v1alpha1 +kind: SpiceDBCluster +metadata: + name: spicedb-custom-sa + namespace: default +spec: + config: + datastoreEngine: postgres + datastoreCredentialsProviderName: "aws-iam" + + # Custom service account name - must match your IAM trust policy + # Trust policy should reference: system:serviceaccount:default:spicedb-custom-service-account + serviceAccountName: "spicedb-custom-service-account" + + extraServiceAccountAnnotations: + eks.amazonaws.com/role-arn: "arn:aws:iam::123456789012:role/spicedb-rds-access-role" + + secretName: spicedb-config + +--- +# Example: SpiceDB with IRSA but standard password authentication +# Use this if you want IRSA for other AWS services but not for RDS auth +apiVersion: authzed.com/v1alpha1 +kind: SpiceDBCluster +metadata: + name: spicedb-irsa-no-rds-iam + namespace: default +spec: + config: + datastoreEngine: postgres + # Note: datastoreCredentialsProviderName is NOT set, so password auth is used + + extraServiceAccountAnnotations: + # The IAM role could grant access to other AWS services + # (e.g., for sidecars or init containers that need AWS access) + eks.amazonaws.com/role-arn: "arn:aws:iam::123456789012:role/spicedb-general-aws-role" + + secretName: spicedb-config-with-password + +--- +# Secret with password-based authentication (for the non-IAM-auth example) +apiVersion: v1 +kind: Secret +metadata: + name: spicedb-config-with-password + namespace: default +stringData: + preshared_key: "your-very-secret-preshared-key" + # Standard password-based connection URI + datastore_uri: "postgresql://spicedb_user:your-password@your-rds-endpoint.region.rds.amazonaws.com:5432/spicedb?sslmode=require"