Skip to content

Instantly share code, notes, and snippets.

@LeoFalco
Created April 15, 2026 13:35
Show Gist options
  • Select an option

  • Save LeoFalco/37ccdae0bad02aa3c098c319fb9c87b5 to your computer and use it in GitHub Desktop.

Select an option

Save LeoFalco/37ccdae0bad02aa3c098c319fb9c87b5 to your computer and use it in GitHub Desktop.
List all GitHub Actions secrets (org + repo level) for a GitHub organization
import { writeFileSync } from 'node:fs'
import { execSync } from 'node:child_process'
const ORG = 'FieldControl'
const OUTPUT_FILE = 'fieldcontrol-secrets.csv'
function gh(args) {
return execSync(`gh ${args}`, { encoding: 'utf-8', timeout: 30_000 }).trim()
}
function ghJson(args) {
const raw = gh(args)
if (!raw) return []
return JSON.parse(raw)
}
const lines = ['scope,repo,secret_name,updated_at']
// Org-level secrets
console.log('Fetching org-level secrets...')
try {
const orgSecrets = ghJson(`api orgs/${ORG}/actions/secrets --paginate --jq '.secrets'`)
for (const secret of orgSecrets) {
lines.push(`org,${ORG},${secret.name},${secret.updated_at}`)
}
console.log(` Found ${orgSecrets.length} org secrets`)
} catch {
console.warn(' Could not list org secrets (needs admin:org scope)')
console.warn(' Run: gh auth refresh -h github.com -s admin:org')
}
// Repo-level secrets
console.log('Fetching repo list...')
const repos = ghJson(`repo list ${ORG} --limit 500 --json name`)
.map(r => r.name)
.sort()
console.log(`Scanning ${repos.length} repos...`)
let repoSecretCount = 0
for (const [i, repo] of repos.entries()) {
try {
const secrets = ghJson(`secret list --repo "${ORG}/${repo}" --json name,updatedAt`)
for (const secret of secrets) {
lines.push(`repo,${repo},${secret.name},${secret.updatedAt}`)
repoSecretCount++
}
} catch {
// skip repos where we can't list secrets
}
if ((i + 1) % 20 === 0) {
console.log(` Progress: ${i + 1}/${repos.length}`)
}
}
console.log(`Found ${repoSecretCount} repo secrets`)
writeFileSync(OUTPUT_FILE, lines.join('\n') + '\n')
console.log(`\nCSV written to ${OUTPUT_FILE} (${lines.length - 1} secrets total)`)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment