# Secrets Management

Source: https://docs.ops0.com/docs/iac/secrets

Securely manage and reference secrets from AWS Secrets Manager, Azure Key Vault, and GCP Secret Manager in your Terraform code.

---

## What is Secrets Management?

ops0 integrates with cloud-native secret management services to help you securely handle sensitive values like API keys, database passwords, and certificates in your infrastructure code. Instead of hardcoding secrets, you can reference them from your cloud provider's secret manager.

**Supported Secret Managers:**
- AWS Secrets Manager
- Azure Key Vault
- GCP Secret Manager

---

## How It Works

### Connect cloud integration
Link your AWS, Azure, or GCP account to your IaC project.

### Create secrets in your cloud provider
Use your cloud provider's console or CLI to create secrets tagged with `ops0-managed`.

### Reference secrets in Terraform
ops0 displays available secrets that you can reference in your code.

### Deploy securely
Secret values are injected at deployment time without exposing them in logs or UI.

---

## AWS Secrets Manager

### AWS Secret Manager Prerequisites

**Requirements**

- AWS integration connected to your project
- Secrets tagged with `ops0-managed: true` or name prefix `ops0-`

### Viewing Available Secrets

### Open Project
Open your IaC project.

### Open Outputs/Secrets
Click the **Outputs/Secrets** button in the toolbar.

### Select Tab
Switch to the **Secrets** tab.

### Choose Provider
Select **AWS** as the provider.

ops0 displays all secrets from AWS Secrets Manager that match the filter criteria.

### Create AWS Secrets with Terraform

```hcl
resource "aws_secretsmanager_secret" "database_password" {
  name        = "ops0-${var.project_name}-db-password"
  description = "Database master password"

  tags = {
    "ops0-managed" = "true"
    "ops0-project" = var.project_name
    "environment"  = "production"
  }
}

resource "aws_secretsmanager_secret_version" "database_password" {
  secret_id     = aws_secretsmanager_secret.database_password.id
  secret_string = random_password.db_password.result
}
```

### Reference AWS Secrets

Use the `aws_secretsmanager_secret_version` data source to reference existing secrets:

```hcl
data "aws_secretsmanager_secret_version" "api_key" {
  secret_id = "ops0-my-project-api-key"
}

resource "aws_lambda_function" "api" {
  function_name = "my-api"

  environment {
    variables = {
      API_KEY = data.aws_secretsmanager_secret_version.api_key.secret_string
    }
  }
}
```

---

## Azure Key Vault

### Azure Key Vault Prerequisites

**Requirements**

- Azure integration connected to your project
- Key Vault accessible to your Azure service principal
- Secrets labeled with `ops0-managed: true`

### Authentication

ops0 uses your Azure service principal credentials to access Key Vault. Ensure your service principal has the **Key Vault Secrets User** role:

```bash
az role assignment create \
  --role "Key Vault Secrets User" \
  --assignee <service-principal-id> \
  --scope /subscriptions/<subscription-id>/resourceGroups/<rg-name>/providers/Microsoft.KeyVault/vaults/<vault-name>
```

### Create Azure Secrets with Terraform

```hcl
resource "azurerm_key_vault_secret" "database_password" {
  name         = "ops0-${var.project_name}-db-password"
  value        = random_password.db_password.result
  key_vault_id = azurerm_key_vault.main.id

  tags = {
    "ops0-managed"     = "true"
    "ops0-project"     = var.project_name
    "ops0-secret-type" = "database-password"
  }
}
```

### Reference Azure Secrets

```hcl
data "azurerm_key_vault_secret" "api_key" {
  name         = "ops0-my-project-api-key"
  key_vault_id = azurerm_key_vault.main.id
}

resource "azurerm_linux_web_app" "app" {
  name                = "my-app"
  resource_group_name = azurerm_resource_group.main.name
  location            = azurerm_resource_group.main.location
  service_plan_id     = azurerm_service_plan.main.id

  app_settings = {
    "API_KEY" = data.azurerm_key_vault_secret.api_key.value
  }
}
```

---

## GCP Secret Manager

### GCP Secret Manager Prerequisites

**Requirements**

- GCP integration connected to your project
- Secrets labeled with `ops0_managed: true`
- Service account with **Secret Manager Secret Accessor** role

### Service Account Permissions

Ensure your GCP service account has the required role:

```bash
gcloud projects add-iam-policy-binding PROJECT_ID \
  --member="serviceAccount:SERVICE_ACCOUNT_EMAIL" \
  --role="roles/secretmanager.secretAccessor"
```

### Create GCP Secrets with Terraform

```hcl
resource "google_secret_manager_secret" "database_password" {
  secret_id = "ops0-${var.project_name}-db-password"

  labels = {
    ops0_managed = "true"
    ops0_project = var.project_name
    environment  = "production"
  }

  replication {
    auto {}
  }
}

resource "google_secret_manager_secret_version" "database_password" {
  secret      = google_secret_manager_secret.database_password.id
  secret_data = random_password.db_password.result
}
```

### Reference GCP Secrets

```hcl
data "google_secret_manager_secret_version" "api_key" {
  secret = "ops0-my-project-api-key"
}

resource "google_cloud_run_service" "api" {
  name     = "my-api"
  location = "us-central1"

  template {
    spec {
      containers {
        image = "gcr.io/my-project/api:latest"

        env {
          name  = "API_KEY"
          value = data.google_secret_manager_secret_version.api_key.secret_data
        }
      }
    }
  }
}
```

---

## Viewing Secrets in ops0

### Accessing the Secrets Panel

### Navigate to Project
Navigate to your IaC project.

### Open the Outputs and Secrets Panel
Click **Outputs/Secrets** in the toolbar.

### Switch Tab
Switch to the **Secrets** tab.

### Select Provider
Select your cloud provider (AWS/Azure/GCP).

### Secret Information Displayed

| Field | Description |
|-------|-------------|
| **Secret name** | The unique identifier |
| **Resource type** | Secret, API key, certificate, etc. |
| **Provider** | AWS, Azure, or GCP |
| **Masked value** | Secrets are never displayed in plain text |

### Copying Secret Values

**Security Note**

Secret values are never displayed in the ops0 UI. Clicking "Copy" securely retrieves the value and places it in your clipboard.

To copy a secret value:

### Click Copy
Click the **Copy** button next to the secret.

### Value Copied
The value is securely fetched and copied to your clipboard.

### Paste
Paste into your local development environment as needed.

---

## Security Best Practices

### Use cloud-native secret managers
Never store secrets in Terraform variables or hardcode them in your code.

### Tag all secrets
Always tag secrets with `ops0-managed` to make them discoverable and manageable.

### Rotate secrets regularly
Set up automatic rotation policies in your cloud provider's secret manager.

### Limit access with IAM
Grant the minimum required permissions to service principals and users.

### Audit secret access
ops0 logs all secret retrievals for compliance and security auditing.

---

## Filtering and Organization

### Naming Convention

Use a consistent naming pattern for ops0-managed secrets:

```
ops0-{project-name}-{secret-type}
```

Examples:
- `ops0-my-app-db-password`
- `ops0-my-app-api-key`
- `ops0-my-app-tls-cert`

### Labeling/Tagging

Add metadata to secrets for better organization:

**AWS:**
```hcl
tags = {
  "ops0-managed" = "true"
  "ops0-project" = "my-app"
  "environment"  = "production"
  "secret-type"  = "database-password"
}
```

**Azure:**
```hcl
tags = {
  "ops0-managed"     = "true"
  "ops0-project"     = "my-app"
  "ops0-secret-type" = "database-password"
}
```

**GCP:**
```hcl
labels = {
  ops0_managed = "true"
  ops0_project = "my-app"
  secret_type  = "database_password"
}
```

---

## Troubleshooting

### Secrets not appearing in ops0

**Check:**
- Secrets are tagged/labeled with `ops0-managed: true` or prefixed with `ops0-`
- Cloud integration is connected to your project
- IAM permissions allow secret listing (e.g., `secretsmanager:ListSecrets` for AWS)

### "Access Denied" when retrieving secret value

**Solutions:**
- Verify service principal has **read** permissions to the specific secret
- For AWS: Check IAM policy includes `secretsmanager:GetSecretValue`
- For Azure: Ensure **Key Vault Secrets User** role is assigned
- For GCP: Verify **Secret Manager Secret Accessor** role

### Secret value is outdated

Secret values are retrieved in real-time. If a value appears outdated:
1. Refresh the secrets list
2. Verify the secret version in your cloud provider console
3. For GCP, check that you're accessing the `latest` version

---

## Next Steps

- [Deployments](https://docs.ops0.com/docs/iac/deployments): Learn how secrets are injected during deployment

- [Advanced Features](https://docs.ops0.com/docs/iac/advanced): Explore Terraform outputs and resource graphs

- [Security](https://docs.ops0.com/docs/settings/compliance): Configure security policies and compliance
