diff --git a/modules/gh-repo-secrets-section/.terraform-docs.yml b/modules/gh-repo-secrets-section/.terraform-docs.yml
new file mode 100644
index 000000000..3a69365ff
--- /dev/null
+++ b/modules/gh-repo-secrets-section/.terraform-docs.yml
@@ -0,0 +1,48 @@
+formatter: "markdown"
+
+version: ""
+
+header-from: docs/header.md
+footer-from: docs/footer.md
+
+recursive:
+ enabled: false
+ path: modules
+ include-main: true
+
+sections:
+ hide: []
+ show: []
+
+content: ""
+
+output:
+ file: "README.md"
+ mode: inject
+ template: |-
+
+ {{ .Content }}
+
+
+output-values:
+ enabled: false
+ from: ""
+
+sort:
+ enabled: true
+ by: name
+
+settings:
+ anchor: true
+ color: true
+ default: true
+ description: false
+ escape: true
+ hide-empty: false
+ html: true
+ indent: 2
+ lockfile: true
+ read-comments: true
+ required: true
+ sensitive: true
+ type: true
diff --git a/modules/gh-repo-secrets-section/README.md b/modules/gh-repo-secrets-section/README.md
new file mode 100644
index 000000000..9bd6bfec6
--- /dev/null
+++ b/modules/gh-repo-secrets-section/README.md
@@ -0,0 +1,117 @@
+
+# **GitHub Repository Secrets Terraform Module**
+
+## Overview
+
+This module manages GitHub repository secrets for **Actions**, **Codespaces**, and **Dependabot** using a single strongly-typed `config` object.
+
+**Important**:
+The `encryptedValue` values passed in the `config` **must already be encrypted** using **libsodium** against the target repository’s public key (GitHub’s recommended method).
+**Terraform does not perform any encryption**. It simply forwards the pre-encrypted value to the GitHub API.
+
+This approach is the most secure for automated pipelines (Prefapp IDP, GitHub Actions, etc.).
+
+## Key Features
+
+- **Single complex object**: All secrets are defined in one `config` variable.
+- **Pre-encrypted values**: `encryptedValue` must be provided already encrypted with libsodium.
+- **Three secret types**: Actions, Codespaces, and Dependabot supported in the same module.
+- **Lifecycle protection**: `ignore_changes` on `encrypted_value` to prevent unnecessary drift.
+- **Full validation**: Enforces required fields and non-empty values.
+- **JSON-native**: Works seamlessly with `terraform.tfvars.json` generated by external programs.
+
+## Basic Usage
+
+### Using `terraform.tfvars.json` (recommended)
+
+```hcl
+module "repo_secrets" {
+ source = "git::https://github.com/prefapp/tfm.git//modules/github-repository-secrets"
+
+ config = var.config # Terraform automatically loads terraform.tfvars.json
+}
+
+### Inline example
+
+Manages GitHub secrets for **one repository only**.
+
+```hcl
+module "secrets" {
+ source = "github.com/prefapp/tfm//modules/gh-repo-secrets-section"
+
+ config = {
+ repository = "prefapp/tfm"
+
+ actions = {
+ "MY\_API\_KEY" = "r+RFBGIn8U7z2Opm5RN7PXKdgFzefXiV91IpG3O2DrClZl9dkTJBfhRZbi2uV2nu..."
+ }
+ codespaces = {}
+ dependabot = {}
+ }
+}
+```
+```
+
+## Requirements
+
+| Name | Version |
+|------|---------|
+| [terraform](#requirement\_terraform) | >= 1.5.0 |
+| [github](#requirement\_github) | ~> 6.0 |
+
+## Providers
+
+| Name | Version |
+|------|---------|
+| [github](#provider\_github) | ~> 6.0 |
+
+## Modules
+
+No modules.
+
+## Resources
+
+| Name | Type |
+|------|------|
+| [github_actions_secret.this](https://registry.terraform.io/providers/integrations/github/latest/docs/resources/actions_secret) | resource |
+| [github_codespaces_secret.this](https://registry.terraform.io/providers/integrations/github/latest/docs/resources/codespaces_secret) | resource |
+| [github_dependabot_secret.this](https://registry.terraform.io/providers/integrations/github/latest/docs/resources/dependabot_secret) | resource |
+| [github_repository.this](https://registry.terraform.io/providers/integrations/github/latest/docs/data-sources/repository) | data source |
+
+## Inputs
+
+| Name | Description | Type | Default | Required |
+|------|-------------|------|---------|:--------:|
+| [config](#input\_config) | Complete configuration object for this module (single repository only).
• repository = GitHub repo in 'owner/repo' format (required)
• actions / codespaces / dependabot = map of secret\_name => encrypted\_value
• encrypted\_value must be pre-encrypted with libsodium using the repo's public key. |
object({
repository = string
actions = optional(map(string), {})
codespaces = optional(map(string), {})
dependabot = optional(map(string), {})
}) | n/a | yes |
+
+## Outputs
+
+| Name | Description |
+|------|-------------|
+| [actions\_secret\_names](#output\_actions\_secret\_names) | List of created Actions secret names |
+| [all\_secret\_names](#output\_all\_secret\_names) | Combined list of all secret names |
+| [codespaces\_secret\_names](#output\_codespaces\_secret\_names) | List of created Codespaces secret names |
+| [dependabot\_secret\_names](#output\_dependabot\_secret\_names) | List of created Dependabot secret names |
+| [repository](#output\_repository) | The repository these secrets belong to |
+
+### 3. `docs/footer.md`
+```markdown
+## Examples
+
+For detailed examples, refer to the [module examples](https://github.com/prefapp/tfm/tree/main/modules/github-repository-secrets/_examples):
+
+- [basic](https://github.com/prefapp/tfm/tree/main/modules/github-repository-secrets/_examples/basic) - Full example with Actions, Codespaces, and Dependabot secrets
+
+## Resources
+
+- **github_actions_secret**: [Official Documentation](https://registry.terraform.io/providers/integrations/github/latest/docs/resources/actions_secret)
+- **github_codespaces_secret**: [Official Documentation](https://registry.terraform.io/providers/integrations/github/latest/docs/resources/codespaces_secret)
+- **github_dependabot_secret**: [Official Documentation](https://registry.terraform.io/providers/integrations/github/latest/docs/resources/dependabot_secret)
+- **GitHub Terraform Provider**: [Official Documentation](https://registry.terraform.io/providers/integrations/github/latest/docs)
+
+## Support
+
+For issues, questions, or contributions related to this module, please visit the [repository's issue tracker](https://github.com/prefapp/tfm/issues).
+
+```
+
\ No newline at end of file
diff --git a/modules/gh-repo-secrets-section/_examples/basic/main.tf b/modules/gh-repo-secrets-section/_examples/basic/main.tf
new file mode 100644
index 000000000..98b21c0ee
--- /dev/null
+++ b/modules/gh-repo-secrets-section/_examples/basic/main.tf
@@ -0,0 +1,5 @@
+module "repo_secrets" {
+ source = "git::https://github.com/prefapp/tfm.git//modules/gh-repo-secrets-section"
+
+ config = var.config # Terraform automatically loads terraform.tfvars.json
+}
diff --git a/modules/gh-repo-secrets-section/_examples/basic/secrets-config.json b/modules/gh-repo-secrets-section/_examples/basic/secrets-config.json
new file mode 100644
index 000000000..a5529b683
--- /dev/null
+++ b/modules/gh-repo-secrets-section/_examples/basic/secrets-config.json
@@ -0,0 +1,13 @@
+{
+ "config": {
+ "actions": {
+ "SECRET_A": "ENCRYPTED_SECRET_A_PLACEHOLDER",
+
+ "SECRET_B": "ENCRYPTED_SECRET_B_PLACEHOLDER"
+ },
+ "codespaces": {
+ "SECRET_C": "ENCRYPTED_SECRET_C_PLACEHOLDER"
+ },
+ "dependabot": {}
+ }
+}
diff --git a/modules/gh-repo-secrets-section/docs/footer.md b/modules/gh-repo-secrets-section/docs/footer.md
new file mode 100644
index 000000000..a220a64f4
--- /dev/null
+++ b/modules/gh-repo-secrets-section/docs/footer.md
@@ -0,0 +1,16 @@
+## Examples
+
+For detailed examples, refer to the [module examples](https://github.com/prefapp/tfm/tree/main/modules/gh-repo-secrets-section/_examples):
+
+- [basic](https://github.com/prefapp/tfm/tree/main/modules/gh-repo-secrets-section/_examples/basic) - Full example with Actions, Codespaces, and Dependabot secrets
+
+## Resources
+
+- **github_actions_secret**: [Official Documentation](https://registry.terraform.io/providers/integrations/github/latest/docs/resources/actions_secret)
+- **github_codespaces_secret**: [Official Documentation](https://registry.terraform.io/providers/integrations/github/latest/docs/resources/codespaces_secret)
+- **github_dependabot_secret**: [Official Documentation](https://registry.terraform.io/providers/integrations/github/latest/docs/resources/dependabot_secret)
+- **GitHub Terraform Provider**: [Official Documentation](https://registry.terraform.io/providers/integrations/github/latest/docs)
+
+## Support
+
+For issues, questions, or contributions related to this module, please visit the [repository's issue tracker](https://github.com/prefapp/tfm/issues).
diff --git a/modules/gh-repo-secrets-section/docs/header.md b/modules/gh-repo-secrets-section/docs/header.md
new file mode 100644
index 000000000..eb7cb5cda
--- /dev/null
+++ b/modules/gh-repo-secrets-section/docs/header.md
@@ -0,0 +1,53 @@
+# **GitHub Repository Secrets Terraform Module**
+
+## Overview
+
+This module manages GitHub repository secrets for **Actions**, **Codespaces**, and **Dependabot** using a single strongly-typed `config` object.
+
+**Important**:
+The `encryptedValue` values passed in the `config` **must already be encrypted** using **libsodium** against the target repository’s public key (GitHub’s recommended method).
+**Terraform does not perform any encryption**. It simply forwards the pre-encrypted value to the GitHub API.
+
+This approach is the most secure for automated pipelines (Prefapp IDP, GitHub Actions, etc.).
+
+## Key Features
+
+- **Single complex object**: All secrets are defined in one `config` variable.
+- **Pre-encrypted values**: `encryptedValue` must be provided already encrypted with libsodium.
+- **Three secret types**: Actions, Codespaces, and Dependabot supported in the same module.
+- **Lifecycle protection**: `ignore_changes` on `encrypted_value` to prevent unnecessary drift.
+- **Full validation**: Enforces required fields and non-empty values.
+- **JSON-native**: Works seamlessly with `terraform.tfvars.json` generated by external programs.
+
+## Basic Usage
+
+### Using `terraform.tfvars.json` (recommended)
+
+```hcl
+module "repo_secrets" {
+ source = "git::https://github.com/prefapp/tfm.git//modules/gh-repo-secrets-section"
+
+ config = var.config # Terraform automatically loads terraform.tfvars.json
+}
+```
+
+### Inline example
+
+Manages GitHub secrets for **one repository only**.
+
+```hcl
+<<<<<<< HEAD
+module "repo_secrets" {
+ source = "git::https://github.com/prefapp/tfm.git//modules/gh-repo-secrets-section"
+
+ config = {
+ repository = "prefapp/tfm"
+
+ actions = {
+ "MY_API_KEY" = "r+RFBGIn8U7z2Opm5RN7PXKdgFzefXiV91IpG3O2DrClZl9dkTJBfhRZbi2uV2nu..."
+ }
+ codespaces = {}
+ dependabot = {}
+ }
+}
+```
diff --git a/modules/gh-repo-secrets-section/main.tf b/modules/gh-repo-secrets-section/main.tf
new file mode 100644
index 000000000..6db1e0a34
--- /dev/null
+++ b/modules/gh-repo-secrets-section/main.tf
@@ -0,0 +1,51 @@
+# ─────────────────────────────────────────────────────────────
+# Fetch repository info (validates existence + gives canonical name)
+# ─────────────────────────────────────────────────────────────
+data "github_repository" "this" {
+ full_name = var.config.repository
+}
+
+# ─────────────────────────────────────────────────────────────
+# GitHub Actions Secrets
+# ─────────────────────────────────────────────────────────────
+resource "github_actions_secret" "this" {
+ for_each = var.config.actions
+
+ repository = data.github_repository.this.name
+ secret_name = each.key
+ encrypted_value = each.value
+
+ lifecycle {
+ ignore_changes = [encrypted_value]
+ }
+}
+
+# ─────────────────────────────────────────────────────────────
+# GitHub Codespaces Secrets
+# ─────────────────────────────────────────────────────────────
+resource "github_codespaces_secret" "this" {
+ for_each = var.config.codespaces
+
+ repository = data.github_repository.this.name
+ secret_name = each.key
+ encrypted_value = each.value
+
+ lifecycle {
+ ignore_changes = [encrypted_value]
+ }
+}
+
+# ─────────────────────────────────────────────────────────────
+# GitHub Dependabot Secrets
+# ─────────────────────────────────────────────────────────────
+resource "github_dependabot_secret" "this" {
+ for_each = var.config.dependabot
+
+ repository = data.github_repository.this.name
+ secret_name = each.key
+ encrypted_value = each.value
+
+ lifecycle {
+ ignore_changes = [encrypted_value]
+ }
+}
diff --git a/modules/gh-repo-secrets-section/outputs.tf b/modules/gh-repo-secrets-section/outputs.tf
new file mode 100644
index 000000000..ad9338624
--- /dev/null
+++ b/modules/gh-repo-secrets-section/outputs.tf
@@ -0,0 +1,28 @@
+output "repository" {
+ description = "The repository these secrets belong to"
+ value = var.config.repository
+}
+
+output "actions_secret_names" {
+ description = "List of created Actions secret names"
+ value = keys(var.config.actions)
+}
+
+output "codespaces_secret_names" {
+ description = "List of created Codespaces secret names"
+ value = keys(var.config.codespaces)
+}
+
+output "dependabot_secret_names" {
+ description = "List of created Dependabot secret names"
+ value = keys(var.config.dependabot)
+}
+
+output "all_secret_names" {
+ description = "Combined list of all secret names"
+ value = concat(
+ keys(var.config.actions),
+ keys(var.config.codespaces),
+ keys(var.config.dependabot)
+ )
+}
diff --git a/modules/gh-repo-secrets-section/variables.tf b/modules/gh-repo-secrets-section/variables.tf
new file mode 100644
index 000000000..e778998a0
--- /dev/null
+++ b/modules/gh-repo-secrets-section/variables.tf
@@ -0,0 +1,24 @@
+variable "config" {
+ description = <<-EOT
+ Complete configuration object for this module (single repository only).
+
+ • repository = GitHub repo in 'owner/repo' format (required)
+ • actions / codespaces / dependabot = map of secret_name => encrypted_value
+ • encrypted_value must be pre-encrypted with libsodium using the repo's public key.
+ EOT
+
+ type = object({
+ repository = string
+
+ actions = optional(map(string), {})
+ codespaces = optional(map(string), {})
+ dependabot = optional(map(string), {})
+ })
+
+ validation {
+ condition = can(regex("^[a-zA-Z0-9_-]+/[a-zA-Z0-9_.-]+$", var.config.repository))
+ error_message = "config.repository must be in 'owner/repo' format."
+ }
+
+ nullable = false
+}
diff --git a/modules/gh-repo-secrets-section/versions.tf b/modules/gh-repo-secrets-section/versions.tf
new file mode 100644
index 000000000..952a90543
--- /dev/null
+++ b/modules/gh-repo-secrets-section/versions.tf
@@ -0,0 +1,10 @@
+terraform {
+ required_version = ">= 1.5.0"
+
+ required_providers {
+ github = {
+ source = "integrations/github"
+ version = "~> 6.0"
+ }
+ }
+}
diff --git a/release-please-config.json b/release-please-config.json
index 1791e861c..8b5a97438 100644
--- a/release-please-config.json
+++ b/release-please-config.json
@@ -151,6 +151,9 @@
"modules/aws-secretsmanager-replication": {
"package-name": "aws-secretsmanager-replication"
},
+ "modules/gh-repo-secrets-section": {
+ "package-name": "gh-repo-secrets-section"
+ },
"modules/azure-vnet-gateway": {
"package-name": "azure-vnet-gateway"
},