Sync Secrets from 1Password #35
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: Sync Secrets from 1Password | |
| on: | |
| workflow_dispatch: | |
| inputs: | |
| dry_run: | |
| description: 'Perform a dry run (no changes made)' | |
| required: false | |
| default: false | |
| type: boolean | |
| debug: | |
| description: 'Enable debug logging' | |
| required: false | |
| default: false | |
| type: boolean | |
| schedule: | |
| # Run weekly on Sundays at 2 AM UTC to sync secrets | |
| - cron: '0 2 * * 0' | |
| permissions: | |
| contents: write | |
| issues: write | |
| jobs: | |
| sync-secrets: | |
| name: Sync 1Password to GitHub Secrets | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Checkout repository | |
| uses: actions/checkout@v4 | |
| - name: Validate required secrets | |
| run: | | |
| echo "π Validating required secrets..." | |
| if [ -z "${{ secrets.OP_SERVICE_ACCOUNT_TOKEN }}" ]; then | |
| echo "β ERROR: OP_SERVICE_ACCOUNT_TOKEN secret is not set" | |
| echo "" | |
| echo "To fix this issue:" | |
| echo "1. Go to 1Password β Settings β Service Accounts" | |
| echo "2. Create a new service account or get existing token" | |
| echo "3. Add OP_SERVICE_ACCOUNT_TOKEN to GitHub repository secrets" | |
| echo " Settings β Secrets and variables β Actions β New repository secret" | |
| echo "" | |
| exit 1 | |
| fi | |
| echo "β OP_SERVICE_ACCOUNT_TOKEN is configured" | |
| - name: Install 1Password CLI | |
| uses: 1password/install-cli-action@v1 | |
| - name: Test 1Password authentication | |
| run: | | |
| echo "π Testing 1Password authentication..." | |
| # Test if we can authenticate | |
| if ! op whoami 2>/dev/null; then | |
| echo "β ERROR: 1Password authentication failed" | |
| echo "" | |
| echo "Possible causes:" | |
| echo "1. OP_SERVICE_ACCOUNT_TOKEN has expired" | |
| echo "2. Service account lacks required permissions" | |
| echo "3. Vault 'TerraphimPlatform' is not accessible" | |
| echo "" | |
| echo "To debug locally, run:" | |
| echo " export OP_SERVICE_ACCOUNT_TOKEN='your-token'" | |
| echo " op whoami" | |
| echo "" | |
| exit 1 | |
| fi | |
| echo "β 1Password authentication successful" | |
| # Check vault access | |
| echo "π Checking vault access..." | |
| if ! op vault get "TerraphimPlatform" --format=json 2>/dev/null | head -1; then | |
| echo "β οΈ WARNING: Cannot access vault 'TerraphimPlatform'" | |
| echo "The service account may not have access to this vault." | |
| else | |
| echo "β Vault 'TerraphimPlatform' is accessible" | |
| fi | |
| env: | |
| OP_SERVICE_ACCOUNT_TOKEN: ${{ secrets.OP_SERVICE_ACCOUNT_TOKEN }} | |
| - name: Check for GH_PAT secret | |
| id: check-pat | |
| run: | | |
| if [ -z "${{ secrets.GH_PAT }}" ]; then | |
| echo "β οΈ GH_PAT secret is not set" | |
| echo "GITHUB_TOKEN cannot write repository secrets." | |
| echo "" | |
| echo "To fix this issue:" | |
| echo "1. Create a GitHub PAT at: https://github.com/settings/tokens" | |
| echo "2. Grant 'repo' scope (full control of private repositories)" | |
| echo "3. Add GH_PAT to repository secrets manually" | |
| echo "" | |
| echo "has_pat=false" >> $GITHUB_OUTPUT | |
| else | |
| echo "β GH_PAT is configured" | |
| echo "has_pat=true" >> $GITHUB_OUTPUT | |
| fi | |
| - name: Sync secrets to GitHub (Dry Run) | |
| if: inputs.dry_run | |
| run: | | |
| echo "π§ͺ Performing dry run - no changes will be made" | |
| ./scripts/sync-secrets-to-github.sh --dry-run | |
| env: | |
| OP_SERVICE_ACCOUNT_TOKEN: ${{ secrets.OP_SERVICE_ACCOUNT_TOKEN }} | |
| GH_TOKEN: ${{ secrets.GH_PAT || secrets.GITHUB_TOKEN }} | |
| - name: Sync secrets to GitHub | |
| if: ${{ !inputs.dry_run && steps.check-pat.outputs.has_pat == 'true' }} | |
| run: | | |
| echo "π Syncing secrets from 1Password to GitHub" | |
| ./scripts/sync-secrets-to-github.sh | |
| env: | |
| OP_SERVICE_ACCOUNT_TOKEN: ${{ secrets.OP_SERVICE_ACCOUNT_TOKEN }} | |
| GH_TOKEN: ${{ secrets.GH_PAT }} | |
| - name: Skip sync (no PAT) | |
| if: ${{ !inputs.dry_run && steps.check-pat.outputs.has_pat != 'true' }} | |
| run: | | |
| echo "β Cannot sync secrets: GH_PAT is required but not set" | |
| echo "GITHUB_TOKEN does not have permission to write repository secrets." | |
| echo "" | |
| echo "Please add a GH_PAT secret with 'repo' scope to enable automatic secret syncing." | |
| exit 1 | |
| - name: Verify deployment after sync | |
| if: ${{ !inputs.dry_run && steps.check-pat.outputs.has_pat == 'true' }} | |
| run: | | |
| echo "π Testing deployment with synced secrets" | |
| # Trigger the deploy workflow to test the synced secrets | |
| gh workflow run deploy.yml --ref ${{ github.ref }} | |
| env: | |
| GH_TOKEN: ${{ secrets.GH_PAT }} | |
| - name: Summary | |
| run: | | |
| echo "## π Secret Sync Summary" >> $GITHUB_STEP_SUMMARY | |
| echo "" >> $GITHUB_STEP_SUMMARY | |
| echo "- **Repository**: ${{ github.repository }}" >> $GITHUB_STEP_SUMMARY | |
| echo "- **Triggered by**: ${{ github.event_name }}" >> $GITHUB_STEP_SUMMARY | |
| echo "- **Dry run**: ${{ inputs.dry_run || 'false' }}" >> $GITHUB_STEP_SUMMARY | |
| echo "- **Status**: β Completed successfully" >> $GITHUB_STEP_SUMMARY | |
| echo "" >> $GITHUB_STEP_SUMMARY | |
| if [[ "${{ inputs.dry_run }}" == "true" ]]; then | |
| echo "No changes were made during this dry run." >> $GITHUB_STEP_SUMMARY | |
| else | |
| echo "Secrets have been synced from 1Password to GitHub repository secrets." >> $GITHUB_STEP_SUMMARY | |
| echo "The deployment workflow has been triggered to verify the synced secrets." >> $GITHUB_STEP_SUMMARY | |
| fi | |
| echo "" >> $GITHUB_STEP_SUMMARY | |
| echo "### π Next Steps" >> $GITHUB_STEP_SUMMARY | |
| echo "- Monitor the deployment workflow for any issues" >> $GITHUB_STEP_SUMMARY | |
| echo "- Check 1Password audit logs for secret access" >> $GITHUB_STEP_SUMMARY | |
| echo "- Consider rotating secrets if needed" >> $GITHUB_STEP_SUMMARY | |
| notify-on-failure: | |
| name: Notify on Sync Failure | |
| runs-on: ubuntu-latest | |
| needs: sync-secrets | |
| if: failure() && !cancelled() | |
| steps: | |
| - name: Create issue on failure | |
| uses: actions/github-script@v7 | |
| with: | |
| script: | | |
| const title = 'π¨ Secret Sync Failed'; | |
| const body = `## Secret Sync Failure | |
| The automated sync from 1Password to GitHub secrets has failed. | |
| **Details:** | |
| - **Repository**: ${{ github.repository }} | |
| - **Workflow**: ${{ github.workflow }} | |
| - **Run ID**: ${{ github.run_id }} | |
| - **Triggered by**: ${{ github.event_name }} | |
| - **Time**: ${{ github.event.head_commit.timestamp || github.event.repository.updated_at }} | |
| **Action Required:** | |
| 1. Check the workflow logs: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }} | |
| 2. Verify 1Password service account permissions | |
| 3. Check GitHub token permissions | |
| 4. Manually run: \`./scripts/sync-secrets-to-github.sh --dry-run\` | |
| 5. Fix any issues and re-run the sync | |
| **Monitoring:** | |
| - Deployment may fail until secrets are synced | |
| - Check 1Password audit logs for authentication issues | |
| - Verify repository secrets in Settings > Secrets and variables > Actions | |
| This issue was created automatically by the sync-secrets workflow.`; | |
| // Check if issue already exists | |
| const { data: issues } = await github.rest.issues.listForRepo({ | |
| owner: context.repo.owner, | |
| repo: context.repo.repo, | |
| state: 'open', | |
| labels: 'automation,secrets,1password' | |
| }); | |
| const existingIssue = issues.find(issue => issue.title === title); | |
| if (!existingIssue) { | |
| await github.rest.issues.create({ | |
| owner: context.repo.owner, | |
| repo: context.repo.repo, | |
| title: title, | |
| body: body, | |
| labels: ['bug', 'automation', 'secrets', '1password', 'high-priority'] | |
| }); | |
| console.log('Created new issue for secret sync failure'); | |
| } else { | |
| await github.rest.issues.createComment({ | |
| owner: context.repo.owner, | |
| repo: context.repo.repo, | |
| issue_number: existingIssue.number, | |
| body: `Another secret sync failure occurred at ${{ github.event.head_commit.timestamp || github.event.repository.updated_at }}.\n\nWorkflow run: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}` | |
| }); | |
| console.log('Added comment to existing secret sync failure issue'); | |
| } |