{"id":15757481,"url":"https://github.com/cbrgm/sync-secrets-action","last_synced_at":"2026-03-01T14:03:45.994Z","repository":{"id":224124940,"uuid":"732813468","full_name":"cbrgm/sync-secrets-action","owner":"cbrgm","description":"Sync Repository, Dependabot and Codespaces secrets + variables between GitHub repositories","archived":false,"fork":false,"pushed_at":"2026-02-27T18:07:44.000Z","size":322,"stargazers_count":5,"open_issues_count":0,"forks_count":1,"subscribers_count":1,"default_branch":"main","last_synced_at":"2026-02-27T22:23:02.303Z","etag":null,"topics":["actions","github","github-actions","go","secret-management","secrets","sync"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/cbrgm.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":"CODEOWNERS","security":"SECURITY.md","support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null},"funding":{"ko_fi":"chrisbargmann"}},"created_at":"2023-12-17T22:38:21.000Z","updated_at":"2026-02-27T18:07:49.000Z","dependencies_parsed_at":"2026-01-06T17:06:41.052Z","dependency_job_id":null,"html_url":"https://github.com/cbrgm/sync-secrets-action","commit_stats":{"total_commits":70,"total_committers":4,"mean_commits":17.5,"dds":0.5142857142857142,"last_synced_commit":"3fe37263e79f42f993f778f413045516736a64ad"},"previous_names":["cbrgm/sync-secrets-action"],"tags_count":42,"template":false,"template_full_name":null,"purl":"pkg:github/cbrgm/sync-secrets-action","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cbrgm%2Fsync-secrets-action","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cbrgm%2Fsync-secrets-action/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cbrgm%2Fsync-secrets-action/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cbrgm%2Fsync-secrets-action/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/cbrgm","download_url":"https://codeload.github.com/cbrgm/sync-secrets-action/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cbrgm%2Fsync-secrets-action/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29970545,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-03-01T13:32:00.443Z","status":"ssl_error","status_checked_at":"2026-03-01T13:32:00.084Z","response_time":124,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["actions","github","github-actions","go","secret-management","secrets","sync"],"created_at":"2024-10-04T09:21:30.793Z","updated_at":"2026-03-01T14:03:45.971Z","avatar_url":"https://github.com/cbrgm.png","language":"Go","funding_links":["https://ko-fi.com/chrisbargmann"],"categories":[],"sub_categories":[],"readme":"# Sync Secrets Action\n\n**Sync Repository, Dependabot and Codespaces secrets + variables between GitHub repositories**\n\n[![GitHub release](https://img.shields.io/github/release/cbrgm/sync-secrets-action.svg)](https://github.com/cbrgm/sync-secrets-action)\n[![Go Report Card](https://goreportcard.com/badge/github.com/cbrgm/sync-secrets-action)](https://goreportcard.com/report/github.com/cbrgm/sync-secrets-action)\n[![go-lint-test](https://github.com/cbrgm/sync-secrets-action/actions/workflows/go-lint-test.yml/badge.svg)](https://github.com/cbrgm/sync-secrets-action/actions/workflows/go-lint-test.yml)\n[![go-binaries](https://github.com/cbrgm/sync-secrets-action/actions/workflows/go-binaries.yml/badge.svg)](https://github.com/cbrgm/sync-secrets-action/actions/workflows/go-binaries.yml)\n[![container](https://github.com/cbrgm/sync-secrets-action/actions/workflows/container.yml/badge.svg)](https://github.com/cbrgm/sync-secrets-action/actions/workflows/container.yml)\n\n- [Sync Secrets Action](#sync-secrets-action)\n   * [Inputs](#inputs)\n   * [GitHub Token Requirements](#github-token-requirements)\n   * [Container Usage](#container-usage)\n   * [Usage Examples](#usage-examples)\n      + [Syncing Repository Secrets and Variables](#syncing-repository-secrets-and-variables)\n      + [Syncing Multi-Line Secrets](#syncing-multi-line-secrets-certificates-private-keys-etc)\n      + [Matrix Build Example - Syncing Across Multiple Repositories](#matrix-build-example-syncing-across-multiple-repositories)\n      + [Query Example - Syncing to Repositories by Search Query](#query-example-syncing-to-repositories-by-search-query)\n      + [Syncing Environment Secrets](#advanced-usage-syncing-environment-secrets)\n      + [Syncing Secrets Across Multiple Repositories and Environments](#sync-secrets-across-multiple-repositories-and-environments)\n      + [Syncing Codespaces Secrets](#syncing-codespaces-secrets)\n      + [Syncing Dependabot Secrets](#syncing-dependabot-secrets)\n      + [Local Development](#local-development)\n   * [High-Level Functionality](#high-level-functionality)\n   * [FAQ on Security](#faq-on-security)\n      + [Is it safe to use this GitHub Action for syncing secrets?](#is-it-safe-to-use-this-github-action-for-syncing-secrets)\n      + [Can others see my secrets during the sync process?](#can-others-see-my-secrets-during-the-sync-process)\n      + [Are my secrets protected from unauthorized access?](#are-my-secrets-protected-from-unauthorized-access)\n      + [Does this action keep my secrets safe even in public repositories?](#does-this-action-keep-my-secrets-safe-even-in-public-repositories)\n      + [Will using this action increase the risk of secret leakage?](#will-using-this-action-increase-the-risk-of-secret-leakage)\n   * [Why yet another action?](#why-yet-another-action)\n   * [Contributing \u0026 License](#contributing-license)\n\n## Inputs\n\n- `github-token`: **Required** - The GitHub token to use. Use GitHub secrets for security.\n- `target`: Optional - The repository to sync secrets and variables to. Either `target` or `query` must be set, but not both.\n- `secrets`: Optional - Secrets to sync. Supports two formats: newline-separated `KEY=VALUE` pairs (default) or JSON object format for multi-line values.\n- `variables`: Optional - Variables to sync. Supports two formats: newline-separated `KEY=VALUE` pairs (default) or JSON object format for multi-line values.\n- `rate-limit`: Optional - Enables rate limit checking. Set to `true` to enable. Default is `false`.\n- `max-retries`: Optional - Maximum number of retries for operations. Must not be smaller than zero. Default is `3`.\n- `dry-run`: Optional - Dry run mode. If true, no changes will be made. Useful for testing. Default is `false`.\n- `prune`: Optional - Prunes all existing secrets and variables not in the subset of those defined. Default is `false`.\n- `environment`: Optional - The GitHub environment to sync variables or secrets to. Use when targeting environment-specific secrets or variables.\n- `type`: Optional - Type of the secrets to manage: `actions`, `dependabot`, or `codespaces`. Default is `actions`.\n- `query`: Optional - GitHub search query to find repositories for batch processing. Either `query` or `target` must be set, but not both.\n\n## GitHub Token Requirements\n\n\u003e **Note**: To use Sync Secrets Action, you need a GitHub Token with the right permissions. The default `GITHUB_TOKEN` won't work.\n\nFor a Personal Access Token (PAT), create one in your GitHub settings with `repo` and, if needed, `admin:org` permissions.\n\nFor a GitHub App token, create an app in GitHub settings, set necessary permissions, install it to target repositories, and use the private key for authentication.\n\nStore your token in GitHub secrets and use it in the `github-token` input of the action.\n\n## Container Usage\n\nThis action can be executed independently from workflows within a container. To do so, use the following command:\n\n```\npodman run --rm -it ghcr.io/cbrgm/sync-secrets-action:v1 --help\n```\n\n## Usage Examples\n\nHere are some usage examples to help you getting started! Feel free to contribute more.\n\n### Syncing Repository Secrets and Variables\n\n```yaml\nname: Sync Repository Secrets and Variables\n\non:\n  workflow_dispatch:\n\njobs:\n  sync-repo-secrets-and-vars:\n    runs-on: ubuntu-latest\n    steps:\n      - name: Sync Secrets and Variables\n        uses: cbrgm/sync-secrets-action@v1\n        with:\n          github-token: ${{ secrets.GITHUB_TOKEN }}\n          target: 'user/repository'\n          secrets: |\n            SECRET_KEY=${{ secrets.SOME_SECRET }}\n            ANOTHER_SECRET=${{ secrets.ANOTHER_SECRET }}\n          variables: |\n            VAR_KEY=varvalue\n            ANOTHER_VAR=${{ secrets.A_VARIABLE }}\n\n```\n\n### Syncing Multi-Line Secrets (Certificates, Private Keys, etc.)\n\nFor secrets that contain newlines (like certificates, private keys, or SSH keys), use JSON format. The action auto-detects JSON when the input starts with `{` and ends with `}`.\n\n**Important**: Use GitHub's `toJSON()` function to properly escape secret values. This ensures that newlines, quotes, and other special characters are correctly encoded in the JSON.\n\n```yaml\nname: Sync Multi-Line Secrets\n\non:\n  workflow_dispatch:\n\njobs:\n  sync-multiline-secrets:\n    runs-on: ubuntu-latest\n    steps:\n      - name: Sync Certificate and Private Key\n        uses: cbrgm/sync-secrets-action@v1\n        with:\n          github-token: ${{ secrets.GITHUB_TOKEN }}\n          target: 'user/repository'\n          secrets: |\n            {\"TLS_CERT\": ${{ toJSON(secrets.TLS_CERT) }}, \"TLS_KEY\": ${{ toJSON(secrets.TLS_KEY) }}}\n```\n\nFor a single multi-line secret:\n\n```yaml\n      - name: Sync SSH Key\n        uses: cbrgm/sync-secrets-action@v1\n        with:\n          github-token: ${{ secrets.GITHUB_TOKEN }}\n          target: 'user/repository'\n          secrets: |\n            {\"SSH_PRIVATE_KEY\": ${{ toJSON(secrets.SSH_PRIVATE_KEY) }}}\n```\n\n\u003e **Note**: When using JSON format, secret keys are automatically converted to uppercase. Values are preserved exactly as provided, including any whitespace or newlines. The `toJSON()` function properly escapes newlines as `\\n` and handles special characters like quotes.\n\n### Matrix Build Example - Syncing Across Multiple Repositories\n\n```yaml\nname: Sync Secrets Across Repositories\n\non:\n  workflow_dispatch:\n\njobs:\n  sync-secrets-across-repos:\n    runs-on: ubuntu-latest\n    strategy:\n      matrix:\n        target: ['user/repo1', 'user/repo2', 'user/repo3']\n    steps:\n      - name: Sync Secrets to ${{ matrix.target }}\n        uses: cbrgm/sync-secrets-action@v1\n        with:\n          github-token: ${{ secrets.GITHUB_TOKEN }}\n          target: ${{ matrix.target }}\n          secrets: |\n            GLOBAL_SECRET=${{ secrets.GLOBAL_SECRET }}\n          variables: |\n            GLOBAL_VAR=globalvarvalue\n```\n\n### Query Example - Syncing to Repositories by Search Query\n\n```yaml\nname: Sync Secrets to Repositories by Query\n\non:\n  workflow_dispatch:\n\njobs:\n  sync-secrets-by-query:\n    runs-on: ubuntu-latest\n    steps:\n      - name: Sync Secrets to Repositories Matching Query\n        uses: cbrgm/sync-secrets-action@v1\n        with:\n          github-token: ${{ secrets.GITHUB_TOKEN }}\n          query: 'org:myorganization topic:mytopic'\n          secrets: |\n            GLOBAL_SECRET=${{ secrets.GLOBAL_SECRET }}\n          variables: |\n            GLOBAL_VAR=globalvarvalue\n```\n\n\u003e This workflow uses the query argument to target repositories within `myorganization` that are tagged with the topic `mytopic`. It syncs the specified secrets and variables to all matching repositories.\n\nSee [GitHub Queries](https://docs.github.com/en/graphql/reference/queries).\n\n### Syncing Environment Secrets\n\n\u003e Tip: Make sure these environments exist before distributing secrets!\n\n```yaml\nname: Sync Environment Secrets\n\non:\n  push:\n    branches:\n      - main\n\njobs:\n  sync-env-secrets:\n    runs-on: ubuntu-latest\n    steps:\n      - name: Sync Environment Secrets\n        uses: cbrgm/sync-secrets-action@v1\n        with:\n          github-token: ${{ secrets.GITHUB_TOKEN }}\n          target: 'user/repository'\n          environment: 'production'\n          secrets: |\n            PROD_DB_PASSWORD=${{ secrets.PROD_DB_PASSWORD }}\n          dry-run: 'false'\n          prune: 'true'\n\n```\n\n### Syncing Secrets Across Multiple Repositories and Environments\n\n```yaml\nname: Sync Secrets Across Repositories and Environments\n\non:\n  workflow_dispatch:\n\njobs:\n  sync-secrets:\n    runs-on: ubuntu-latest\n    strategy:\n      matrix:\n        repo: ['org/repo1', 'org/repo2', 'org/repo3'] # Target repositories\n        environment: ['development', 'staging', 'production'] # Target environments\n    steps:\n      - name: Sync Secrets to ${{ matrix.repo }} for ${{ matrix.environment }} Environment\n        uses: cbrgm/sync-secrets-action@v1\n        with:\n          github-token: ${{ secrets.GITHUB_TOKEN }}\n          target: ${{ matrix.repo }}\n          environment: ${{ matrix.environment }}\n          secrets: |\n            DATABASE_URL=${{ secrets['DB_URL_' + matrix.environment] }}\n            API_KEY=${{ secrets['API_KEY_' + matrix.environment] }}\n          type: 'actions'\n          dry-run: 'false'\n          prune: 'true'\n```\n\n\u003e  The secrets input dynamically references secrets based on the environment. For example, `DB_URL_development`, `DB_URL_staging`, and `DB_URL_production` should be defined in your repository's secrets. This approach allows each job to use environment-specific secret values.\n\n### Syncing Codespaces Secrets\n\n```yaml\nname: Sync Codespaces Secrets\n\non:\n  workflow_dispatch:\n\njobs:\n  sync-codespaces-secrets:\n    runs-on: ubuntu-latest\n    steps:\n      - name: Sync Codespaces Secrets\n        uses: cbrgm/sync-secrets-action@v1\n        with:\n          github-token: ${{ secrets.GITHUB_TOKEN }}\n          target: 'user/repository'\n          secrets: |\n            CODESPACE_SECRET=${{ secrets.CODESPACE_SECRET }}\n          type: 'codespaces'\n\n```\n\n### Syncing Dependabot Secrets\n\n```yaml\nname: Sync Dependabot Secrets\n\non:\n  workflow_dispatch:\n\njobs:\n  sync-dependabot-secrets:\n    runs-on: ubuntu-latest\n    steps:\n      - name: Sync Dependabot Secrets\n        uses: cbrgm/sync-secrets-action@v1\n        with:\n          github-token: ${{ secrets.GITHUB_TOKEN }}\n          target: 'user/repository'\n          secrets: |\n            DEPENDABOT_SECRET=${{ secrets.DEPENDABOT_SECRET }}\n          type: 'dependabot'\n```\n\n### Local Development\n\nYou can build this action from source using `Go`:\n\n```bash\nmake build\n```\n\n## High-Level Functionality\n\n```mermaid\nsequenceDiagram\n    participant CronUser as Cron / User\n    participant GitHubAction\n    participant GitHubAPI\n    participant Repository\n\n    CronUser-\u003e\u003e+GitHubAction: Execute Action\n    GitHubAction-\u003e\u003e+GitHubAPI: Create API Client\n    GitHubAPI-\u003e\u003e-GitHubAction: Client Created\n    GitHubAction-\u003e\u003eGitHubAction: Parse Secrets \u0026 Variables\n    GitHubAction-\u003e\u003e+GitHubAPI: Search Repositories (if query provided)\n    GitHubAPI-\u003e\u003e-GitHubAction: Return Repositories\n    GitHubAction-\u003e\u003eGitHubAction: Process Each Repository\n    GitHubAction-\u003e\u003e+Repository: Process Repository\n    alt Environment Specific\n        Repository-\u003e\u003e+GitHubAPI: List Environment Secrets \u0026 Variables Names\n        GitHubAPI-\u003e\u003e-Repository: Update Secrets \u0026 Variables\n    else Repository Specific\n        Repository-\u003e\u003e+GitHubAPI: List Repository Secrets \u0026 Variables Names\n        GitHubAPI-\u003e\u003e-Repository: Update Secrets \u0026 Variables\n    else Dependabot\n        Repository-\u003e\u003e+GitHubAPI: List Dependabot Secrets Names\n        GitHubAPI-\u003e\u003e-Repository: Update Secrets\n    else Codespaces\n        Repository-\u003e\u003e+GitHubAPI: List Codespaces Secrets Names\n        GitHubAPI-\u003e\u003e-Repository: Update Secrets\n    end\n    Repository-\u003e\u003e-GitHubAction: Processing Complete\n    GitHubAction-\u003e\u003e-CronUser: Execution Finished`\n```\n\n## FAQ on Security\n\n### Is it safe to use this GitHub Action for syncing secrets?\n\nYes, it is designed with safety in mind. However, like any tool, the security level depends on proper usage and configuration. Ensure your GitHub token has the minimum required permissions.\n\n### Can others see my secrets during the sync process?\n\nNo, secrets are encrypted and handled within GitHub's secure environment. Yet, be cautious with the output logs and error messages to avoid accidental exposure.\n\n### Are my secrets protected from unauthorized access?\n\nYes, they are protected using GitHub's security mechanisms. Nonetheless, the security is also contingent on how well access controls and permissions are managed in your GitHub repository settings.\n\n### Does this action keep my secrets safe even in public repositories?\n\nYes, secrets are not exposed in code or logs, ensuring they remain secure. However, the inherent risk of public repositories means you should be extra vigilant in monitoring access and usage patterns.\n\n### Will using this action increase the risk of secret leakage?\n\nUsing this action does not inherently increase risk if followed by GitHub's security guidelines and best practices. Risks mainly arise from misconfigurations or improper handling of secrets on the user's part. Regular audits and updates are recommended to maintain security.\n\n## Why yet another action?\n\nWhile building my GitHub Action for secret synchronization, I drew inspiration from existing solutions, focusing on addressing specific challenges and enhancing user experience:\n\n- [Secrets Sync Action by @jpoehnelt](https://github.com/jpoehnelt/secrets-sync-action)\n- [Secrets Sync by @xt0rted](https://github.com/xt0rted/secrets-sync)\n\nKey design principles guiding this action development include:\n\n- **Standardizing Inputs**: Adopting kebab-case for inputs, inspired by the conventions seen in the repositories listed.\n- **Enhancing Matching Logic**: Utilizing GitHub Search syntax over regex for repository targeting.\n- **Explicit Secret Specification**: Preferring direct secret naming to regex patterns for clarity and precision, addressing complexity and confusion observed in the existing actions.\n\n## Contributing \u0026 License\n\n* **Contributions Welcome!**: Interested in improving or adding features? Check the [Contributing Guide](https://github.com/cbrgm/sync-secrets-action/blob/main/CONTRIBUTING.md) for instructions on submitting changes and setting up development environment.\n* **Free \u0026 Open**: Made during free time, costs nothing. See [Apache 2.0 License](https://github.com/cbrgm/sync-secrets-action/blob/main/LICENSE) for your rights.\n* **Your Involvement Matters**: Code contributions, suggestions, feedback crucial for improvement and success. Let's maintain it as a useful resource for all 🌍.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcbrgm%2Fsync-secrets-action","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcbrgm%2Fsync-secrets-action","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcbrgm%2Fsync-secrets-action/lists"}