Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions .github/workflows/helm-release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@ on:
- "helm-charts/**"
- "manifests/**"
- "scripts/publish-helm-repo.sh"
- "scripts/verify-published-helm-repo.py"
- "scripts/test_verify_published_helm_repo.py"
- "artifacthub-repo.yml"
- "scripts/test-helm-charts.sh"
- "scripts/check-rbac-manifest.sh"
- "scripts/test_routing_rbac.py"
Expand All @@ -17,6 +20,9 @@ on:
- "helm-charts/**"
- "manifests/**"
- "scripts/publish-helm-repo.sh"
- "scripts/verify-published-helm-repo.py"
- "scripts/test_verify_published_helm_repo.py"
- "artifacthub-repo.yml"
- "scripts/test-helm-charts.sh"
- "scripts/check-rbac-manifest.sh"
- "scripts/test_routing_rbac.py"
Expand Down Expand Up @@ -71,6 +77,9 @@ jobs:
- name: Check routing collector RBAC
run: python3 scripts/test_routing_rbac.py

- name: Test public repository consumer verification
run: python3 scripts/test_verify_published_helm_repo.py

- name: Lint and render
run: scripts/test-helm-charts.sh "$CHART"

Expand Down Expand Up @@ -268,6 +277,9 @@ jobs:
- name: Deploy to GitHub Pages
uses: actions/deploy-pages@d6db90164ac5ed86f2b6aed7e0febac5b3c0c03e # v4.0.5

- name: Verify publicly downloadable index and chart packages
run: python3 scripts/verify-published-helm-repo.py --expected-index _site/index.yaml --expected-repository-metadata artifacthub-repo.yml --attempts 20

- name: Fail when a chart was skipped
run: |
if [ -s skipped.txt ]; then
Expand Down
4 changes: 4 additions & 0 deletions .github/workflows/terraform-validate.yml
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,7 @@ jobs:
- 1.8.5
- 1.10.5
directory:
- gcp-integration-setup/terraform/modules/nullify-gcp-integration
- aws-integration-setup/terraform/modules/eks-managed-scan-access
- aws-integration-setup/terraform/modules/k8s-resources
- aws-integration-setup/terraform/modules/nullify-aws-integration
Expand Down Expand Up @@ -148,6 +149,9 @@ jobs:
- name: compare Allow/Deny action sets
run: python3 scripts/check_iam_policy_drift.py

- name: Check gcloud installer permissions
run: python3 -B scripts/test_gcp_installer.py

- name: Check routing collector RBAC
run: python3 scripts/test_routing_rbac.py

Expand Down
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -171,3 +171,7 @@ values-secret.yml
/published.txt
/release.txt
/skipped.txt

# Python script caches
__pycache__/
*.pyc
42 changes: 30 additions & 12 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# 🛡️ Nullify Cloud Connector - Infrastructure Templates

**Complete infrastructure templates for deploying Nullify's cloud security integrations across Kubernetes and AWS.**
**Complete infrastructure templates for deploying Nullify's cloud security integrations across AWS, GCP, Azure, and supported Kubernetes collection paths.**

> 🚨 **SECURITY NOTICE**: This repository contains **GENERIC TEMPLATES ONLY**. Contact Nullify support for production configuration values.

Expand All @@ -9,10 +9,11 @@
This repository provides comprehensive infrastructure-as-code templates for integrating Nullify's security platform with your cloud environment. It includes multiple deployment options to suit different infrastructure preferences and requirements.

### **What's Included**
- ⚙️ **Helm Charts** - Production-ready Kubernetes deployment for **EKS (IRSA)** and **GKE (Workload Identity)**
- ⚙️ **Helm Charts** - Production-ready Kubernetes deployment for **EKS (IRSA)** and **GKE (projected Kubernetes service-account tokens)**
- 🏗️ **CloudFormation Templates** - AWS infrastructure setup with IAM roles and policies
- 🔧 **Terraform Modules** - Modular infrastructure-as-code for AWS and multi-cluster EKS integration
- ☁️ **GCP Terraform** - Read-only GCP integration via Workload Identity Federation
- **Azure Terraform** - Azure subscription or management-group Reader access via workload federation, with optional directory permissions
- 🤖 **GitHub Actions** - Automated chart publishing and validation
- 📚 **Documentation** - Comprehensive setup and security guides
- ❌ **NO real sensitive data, bucket names, or account IDs**
Expand Down Expand Up @@ -42,7 +43,7 @@ This repository provides comprehensive infrastructure-as-code templates for inte
| **🏗️ CloudFormation** | AWS-centric infrastructure, ClickOps teams | AWS CLI, appropriate IAM permissions |
| **🔧 Terraform (AWS)** | Infrastructure-as-code, multi-cluster teams | Terraform, AWS provider configured |
| **☁️ Terraform (GCP)** | GCP environments, Workload Identity Federation | Terraform, `gcloud` auth on the host project, org or folder admin access |
| **☁️ Terraform (GKE collector)** | GKE clusters running the Nullify k8s-collector | Terraform, GKE with Workload Identity enabled |
| **☁️ Terraform (GKE service account)** | Optional GCP identity resources; not needed for the standard projected-token collector | Terraform; confirm the alternate identity requirement with Nullify |

### **GCP Quick Start**

Expand All @@ -55,15 +56,21 @@ $EDITOR terraform.tfvars # paste values from the Nullify console
terraform init && terraform apply
```

Then paste the `service_account_email` and `workload_identity_provider` outputs into the Nullify console under **Settings → Cloud Integrations → GCP** and click **Verify**.
Then paste the `service_account_email` and `workload_identity_provider` outputs into the Nullify console under **Settings → Connectors → GCP**, select **Save changes**, then **Validate**. Validation checks the saved identity. Confirm fresh inventory separately.

See [`gcp-integration-setup/terraform/README.md`](gcp-integration-setup/terraform/README.md) for the full guide, the org / folder / project scope options, and the gcloud-only installer.

### Azure quick start

Open `azure-integration-setup/terraform`, copy `terraform.tfvars.example`, and fill in the tenant-specific values supplied by Nullify. Choose management-group or subscription scope, review `terraform plan`, then apply it. Paste `entra_tenant_id` and `application_client_id` into **Settings → Connectors → Azure** with Workload Identity Federation selected.

Azure cloud access is separate from Entra sign-in, Azure DevOps, and Teams. The default module grants ARM Reader; optional directory permissions require separate administrator consent. See the [Azure module guide](azure-integration-setup/terraform/README.md).

### **Prerequisites**

**All methods:**
1. **Nullify Account** and dashboard access
2. Log in to **Configure > Integrations** to obtain provider-specific values
2. Log in to **Settings → Connectors** to obtain provider-specific values

**AWS integration:**
- AWS account with IAM permissions
Expand All @@ -78,6 +85,12 @@ See [`gcp-integration-setup/terraform/README.md`](gcp-integration-setup/terrafor

---

## Helm release compatibility

The public Helm index now serves collector chart **0.6.0** with image **4.0.0** and readonly-access chart **0.1.0**. Publication was verified on 11 November 2026 after releasing the queued GitHub Pages workflow. Collector **0.5.0**, with image **3.48.0**, remains available for the existing backend contract. Collector 4 requires `collector.s3.keyPrefix` from a compatible backend. Confirm the backend rollout and exact `collectorUploadPrefix` with Nullify before upgrading. Do not infer the prefix or upgrade only the image.

The current CloudFormation and Terraform collector paths also require the source-prefix contract; pinning Helm 0.5.0 does not make current IAM templates compatible with an older backend. Use the complete template/chart version set confirmed by Nullify.

## ⚙️ **Helm Chart Deployment**

### **Option 1: Install from Helm Repository (Recommended)**
Expand All @@ -102,7 +115,7 @@ serviceAccount:
EOF

# 3. Install the chart
helm install nullify-collector nullify/nullify-k8s-collector \
helm install nullify-collector nullify/nullify-k8s-collector --version 0.5.0 \
-f values-production.yaml \
--namespace nullify \
--create-namespace
Expand All @@ -113,6 +126,8 @@ kubectl get all -n nullify

### **Option 2: Install from Source**

Obtain the exact `collectorUploadPrefix` and confirm source-version compatibility with Nullify before following this path.

```bash
# 1. Clone this repository
git clone https://github.com/Nullify-Platform/nullify-cloud-connector.git
Expand Down Expand Up @@ -360,7 +375,7 @@ nullify-cloud-connector/
├── 🔧 terraform/ # Terraform Modules
│ ├── modules/
│ │ ├── nullify-gcp-integration/ # WIF pool, provider, SA, IAM bindings
│ │ └── nullify-gke-collector/ # GKE k8s-collector deployment
│ │ └── nullify-gke-collector/ # Optional GCP service-account identity resources
│ ├── examples/ # Example configurations
│ ├── terraform.tfvars.example # Example configuration
│ └── README.md # GCP Terraform documentation
Expand All @@ -374,7 +389,7 @@ nullify-cloud-connector/

| Component | Purpose | Use When |
|-----------|---------|----------|
| **🎯 Helm Charts** | Deploy K8s collector (EKS via IRSA, GKE via Workload Identity) | You have EKS or GKE and prefer K8s-native tools |
| **🎯 Helm Charts** | Deploy K8s collector (EKS via IRSA, GKE via projected service-account tokens) | You have EKS or GKE and prefer K8s-native tools |
| **🏗️ CloudFormation** | Set up AWS IAM roles and policies | You prefer AWS-native infrastructure |
| **🔧 Terraform** | Modular infrastructure-as-code with multi-cluster support | You use Terraform for infrastructure |
| **🤖 GitHub Actions** | Automated testing and publishing | You want CI/CD for chart updates |
Expand Down Expand Up @@ -405,7 +420,7 @@ serviceAccount:

### **Basic Configuration**

All required values are provided in the Nullify configure page.
For chart 0.6.0, use the exact source-qualified prefix supplied by a compatible Nullify deployment. Replace every placeholder below; if the prefix is unavailable, stop and request compatible deployment values. Use the earlier 0.5.0 quick start only with the matching existing backend and IAM policy.

```yaml
collector:
Expand All @@ -414,7 +429,7 @@ collector:
clusterName: "your-cluster-name" # Must match your actual EKS cluster name
s3:
bucket: "your-nullify-bucket"
keyPrefix: "k8s-collector"
keyPrefix: "k8s-collector/YOUR-SOURCE-TENANT-ID/"
kms:
keyArn: "arn:aws:kms:us-west-2:123456789012:key/your-key-id"
schedule: "0 2 * * *" # Daily at 2 AM UTC
Expand Down Expand Up @@ -473,9 +488,12 @@ Each release is tagged `<chart>-v<version>` (for example `nullify-k8s-collector-
Collector releases up to 0.2.0 were tagged `vX.Y.Z`; only 0.2.0 of those is still in the repository.

### **Deployment Management**

The following command keeps the 0.5.0 contract. To upgrade to 0.6.0, first complete the [collector 4 cutover](#collector-4-source-prefix-cutover), including paired backend, IAM policy and exact prefix.

```bash
# Upgrade the chart
helm upgrade nullify-collector nullify/nullify-k8s-collector \
# Keep the version used by the existing-backend quick start
helm upgrade nullify-collector nullify/nullify-k8s-collector --version 0.5.0 \
-f values-production.yaml \
--namespace nullify

Expand Down
1 change: 1 addition & 0 deletions artifacthub-repo.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
repositoryID: 158135dc-d5cd-4016-9d22-5494d9510594
17 changes: 10 additions & 7 deletions aws-integration-setup/cloudformation/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ This template creates:

1. **Obtain Configuration Values from Nullify Configure Page**:
- Log in to your Nullify configure page
- Navigate to Configure > Integrations
- Navigate to **Settings → Connectors → AWS**
- Select AWS integration to begin setup
- Note the provided values:
- External ID for your account
Expand All @@ -35,7 +35,7 @@ This template creates:
- OIDC provider URL (see [Getting EKS OIDC URL](#getting-eks-oidc-url) below)
- **Helm charts or Kubernetes manifests** to deploy the collector cronjobs

> 📖 **Reference**: For detailed setup instructions, see the [Nullify AWS Integration Documentation](https://docs.nullify.ai/integrations/aws/configuration).
> 📖 **Reference**: For detailed setup instructions, see the [Nullify AWS Integration Documentation](https://docs.nullify.ai/connectors/aws/configuration).

**Alternative**: Contact Nullify Support for assistance with configuration values.

Expand Down Expand Up @@ -68,10 +68,7 @@ oidc.eks.us-west-2.amazonaws.com/id/ABCDEF1234567890ABCDEF1234567890
3. Go to the **Configuration** tab
4. Under **Details**, look for **OpenID Connect provider URL**

### Method 3: kubectl (if you have cluster access)
```bash
kubectl get configmap aws-auth -n kube-system -o yaml | grep "oidc"
```
The `aws-auth` ConfigMap does not supply the cluster OIDC issuer. Use the AWS CLI or EKS console methods above.

### OIDC URL Format
- **Full URL format**: `https://oidc.eks.REGION.amazonaws.com/id/CLUSTER_ID`
Expand Down Expand Up @@ -127,6 +124,8 @@ aws cloudformation describe-stacks \

### 3. Deploy with EKS Integration

The current EKS collector template requires the exact `CollectorUploadPrefix` from a compatible Nullify backend. Confirm the paired backend rollout and deploy collector 4 with the same prefix. If the value is unavailable, stop and ask Nullify for a complete compatible version set; do not combine the current role policy with a 3.x collector. See the [cutover and rollback requirements](../../README.md#collector-4-source-prefix-cutover). Replace the prefix and KMS placeholders below with supplied deployment values.

```bash
# For EKS clusters, enable integration
# First, get your OIDC URL (see "Getting EKS OIDC URL" section above)
Expand All @@ -142,6 +141,8 @@ aws cloudformation create-stack \
ParameterKey=CrossAccountRoleArn,ParameterValue=arn:aws:iam::NULLIFY-ACCOUNT:role/NULLIFY-ROLE \
ParameterKey=NullifyS3Bucket,ParameterValue=NULLIFY-BUCKET \
ParameterKey=EnableEKSIntegration,ParameterValue=true \
ParameterKey=CollectorUploadPrefix,ParameterValue=k8s-collector/YOUR-SOURCE-TENANT-ID/ \
ParameterKey=NullifyKMSKeyArn,ParameterValue=arn:aws:kms:us-west-2:123456789012:key/YOUR-KEY-ID \
ParameterKey=EKSOidcProviderURL,ParameterValue=$OIDC_URL \
--capabilities CAPABILITY_NAMED_IAM

Expand All @@ -155,7 +156,9 @@ aws cloudformation create-stack \
ParameterKey=CrossAccountRoleArn,ParameterValue=arn:aws:iam::NULLIFY-ACCOUNT:role/NULLIFY-ROLE \
ParameterKey=NullifyS3Bucket,ParameterValue=NULLIFY-BUCKET \
ParameterKey=EnableEKSIntegration,ParameterValue=true \
ParameterKey=EKSOidcProviderURL,ParameterValue=A78D8794A06CAE5791C5812CDB164C7D.gr7.ap-southeast-2.eks.amazonaws.com \
ParameterKey=CollectorUploadPrefix,ParameterValue=k8s-collector/YOUR-SOURCE-TENANT-ID/ \
ParameterKey=NullifyKMSKeyArn,ParameterValue=arn:aws:kms:us-west-2:123456789012:key/YOUR-KEY-ID \
ParameterKey=EKSOidcProviderURL,ParameterValue=oidc.eks.us-west-2.amazonaws.com/id/YOUR-OIDC-ID \
--capabilities CAPABILITY_NAMED_IAM
```

Expand Down
9 changes: 7 additions & 2 deletions aws-integration-setup/terraform-v6/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,10 @@ ephemeral "aws_eks_cluster_auth" "primary" {
token = ephemeral.aws_eks_cluster_auth.primary.token
```

## Collector version compatibility

The current `k8s-resources` module deploys collector 4.0.0 and requires `collector_upload_prefix` whenever the collector is enabled. Obtain the exact `collectorUploadPrefix` and confirm the paired Nullify backend rollout first. Pass that same prefix to the AWS integration role module and each collector module. Do not apply current collector templates to an older backend or upgrade only the image. See the [cutover and rollback requirements](../../README.md#collector-4-source-prefix-cutover). Cloud-only and managed-scan configurations do not need a collector upload prefix.

## Requirements

- Terraform >= 1.8 (>= 1.10 for the `multi-cluster-complete` and `managed-scan` examples)
Expand Down Expand Up @@ -105,6 +109,7 @@ module "nullify_eks_access" {
- `aws_region`: AWS region for IAM resources (default: ap-southeast-2)
- `s3_bucket_name`: S3 bucket for scan results (optional)
- `nullify_s3_access_point_arn`: S3 access point for collector uploads (optional)
- `collector_upload_prefix`: Exact source prefix from Nullify; required on collector module instances and passed to the IAM module for collector 4
- `kms_key_arn`: KMS key ARN or alias ARN from the Nullify configure page; see "KMS" in `../terraform/README.md`. Optional for this module; required by `k8s-resources` whenever `enable_collector` is true
- `enable_kubernetes_integration`: Set to `true` for EKS integration
- `eks_cluster_arns`: List of EKS cluster ARNs to integrate with, in any region
Expand All @@ -115,11 +120,11 @@ module "nullify_eks_access" {
- `tags`: Resource tags
- `cronjob_schedule`: Deprecated and unused here; set the schedule on `k8s-resources`

`k8s-resources` requires `cluster_name` and `kms_key_arn` whenever `enable_collector` is true, with no unencrypted opt-out. `cluster_name` must match your actual cluster name exactly, must match a cluster registered on the Nullify configure page, and must differ per cluster: the collector uploads to `<prefix>/k8s-collector/<cluster_name>-data.json`, and Nullify joins that upload on the name. See "Kubernetes Resources" and "KMS" in `../terraform/README.md`.
`k8s-resources` requires `cluster_name`, `kms_key_arn` and `collector_upload_prefix` whenever `enable_collector` is true, with no unencrypted opt-out. `cluster_name` must match your actual cluster name exactly, must match a cluster registered on the Nullify configure page, and must differ per cluster: the collector uploads to `<prefix>/k8s-collector/<cluster_name>-data.json`, and Nullify joins that upload on the name. See "Kubernetes Resources" and "KMS" in `../terraform/README.md`.

A cluster cannot run the collector and the managed scan at once: the two paths register it under different identities, duplicating its inventory. This is enforced by `eks-managed-scan-access`'s `collector_cluster_arns` variable, not by a `k8s-resources` flag combination -- `enable_collector` and `enable_managed_scan_rbac` may be set together on one `k8s-resources` instance to stage a cutover, since the ClusterRole it applies is inert until an access entry uses it. See "Kubernetes Resources" in `../terraform/README.md`.

`k8s-resources` defaults `collector_image` to `public.ecr.aws/w4o2j2x4/integrations:k8s-collector-3.48.1`, the same tag the Helm chart deploys. Replace any explicit `nullify/k8s-collector:latest`: Nullify does not publish that Docker Hub image.
`k8s-resources` defaults `collector_image` to `public.ecr.aws/w4o2j2x4/integrations:k8s-collector-4.0.0`, the same tag as Helm chart 0.6.0. Both require the collector 4 source-prefix contract. Replace any explicit `nullify/k8s-collector:latest`: Nullify does not publish that Docker Hub image.

## Upgrade Notes

Expand Down
Loading
Loading