Skip to content

Push the tap and bucket with deploy keys, not a PAT - #117

Merged
ralyodio merged 1 commit into
mainfrom
feat/tap-bucket-deploy-keys
Sep 24, 2026
Merged

ralyodio merged 1 commit into
mainfrom
feat/tap-bucket-deploy-keys

Conversation

@ralyodio

Copy link
Copy Markdown
Contributor

Homebrew and Scoop are the two channels we own outright, so they are the two that can be turned on without waiting on anyone.

Both repos already existed (profullstack/homebrew-tap, profullstack/scoop-bucket). Both now carry a write deploy key titled "tronbrowser release automation", with the private half stored as HOMEBREW_TAP_SSH_KEY and SCOOP_BUCKET_SSH_KEY on this repo.

Why a deploy key and not a PAT. A PAT carries the whole account, so any token able to push to the tap could push anywhere else too. GitHub has no API to mint one, so it would have to be pasted in by hand and rotated by hand. A deploy key is scoped to a single repository, can be created through the API, and is revoked by deleting it from that repo.

Two things the first real push turned up:

  • The tap keeps Casks/ (for nightcell7) and had no Formula/ at all. distribution/homebrew/tronbrowser.rb is a Formula, so the push has to create that directory — a tap carries both happily.
  • The bucket needed the same mkdir -p for its first entry.

Verified by actually pushing

tronbrowser 3.15.1 is live in both repos now, and the Formula's linux sha256 matches the published v3.15.1 tarball byte for byte (fd102dbb…7130).

brew install profullstack/tap/tronbrowser resolves for the first time.

🤖 Generated with Claude Code

Homebrew and Scoop are the two channels we own outright, so they are the two we
can actually turn on without waiting for anyone. Both repos already existed
(profullstack/homebrew-tap, profullstack/scoop-bucket) and both now carry a
write deploy key titled "tronbrowser release automation", with the private half
stored as HOMEBREW_TAP_SSH_KEY and SCOOP_BUCKET_SSH_KEY.

A deploy key rather than a PAT. A PAT carries the whole account, so any token
able to push to the tap could also push to every other repo; GitHub has no API
to mint one, so it would have to be pasted in by hand and rotated by hand. A
deploy key is scoped to one repository, can be created through the API, and is
revoked by deleting it from that repo.

Two details the first real push turned up. The tap keeps Casks/ for nightcell7
and had no Formula/ at all, and distribution/homebrew/tronbrowser.rb is a
Formula, so the push has to create the directory; a tap carries both quite
happily. And the bucket needed the same mkdir -p treatment for its first entry.

Verified by pushing for real: tronbrowser 3.15.1 is live in both repos, and the
Formula's linux sha256 matches the published v3.15.1 tarball byte for byte.
`brew install profullstack/tap/tronbrowser` now resolves, which it never has
before.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@github-actions

Copy link
Copy Markdown
Contributor

ThreatCrush Security Scan

52 finding(s)

HIGH/CRITICAL: 3 | MEDIUM: 28 | LOW: 21

Severity Rule Location
HIGH py-ssrf-outbound-request apps/desktop/launcher/tron-tor-helper:303
HIGH py-ssrf-outbound-request apps/desktop/launcher/tron-tor-helper:437
HIGH sh-remote-script-execution apps/web/public/install.sh:757
MEDIUM js-open-redirect apps/desktop/extensions/ai-sidebar/install-helper.js:156
MEDIUM js-unescaped-html-sink apps/desktop/extensions/ai-sidebar/media.js:34
MEDIUM js-unescaped-html-sink apps/desktop/extensions/ai-sidebar/media.js:57
MEDIUM js-unescaped-html-sink apps/desktop/extensions/ai-sidebar/newtab.js:237
MEDIUM js-unescaped-html-sink apps/desktop/extensions/ai-sidebar/newtab.js:266
MEDIUM js-unescaped-html-sink apps/desktop/extensions/ai-sidebar/newtab.js:336
MEDIUM js-unescaped-html-sink apps/desktop/extensions/ai-sidebar/options.js:305
MEDIUM js-unescaped-html-sink apps/desktop/extensions/ai-sidebar/sidepanel.js:78
MEDIUM js-unescaped-html-sink apps/desktop/extensions/ai-sidebar/sidepanel.js:166
MEDIUM js-unescaped-html-sink apps/extensions/public/store.js:77
MEDIUM js-unescaped-html-sink apps/extensions/public/store.js:227
MEDIUM js-unescaped-html-sink apps/extensions/public/store.js:569
MEDIUM js-unescaped-html-sink apps/web/public/app.js:29
MEDIUM js-unescaped-html-sink apps/web/public/dns.js:54
MEDIUM sh-remote-script-execution apps/web/public/install.sh:164
MEDIUM sh-remote-script-execution apps/web/public/install.sh:169
MEDIUM sh-remote-script-execution apps/web/public/install.sh:282
MEDIUM sh-remote-script-execution apps/web/public/install.sh:300
MEDIUM sh-remote-script-execution apps/web/public/install.sh:813
MEDIUM sh-remote-script-execution apps/web/public/install.sh:864
MEDIUM js-unescaped-html-sink apps/web/public/settings.js:96
MEDIUM js-unescaped-html-sink apps/web/public/settings.js:168
MEDIUM js-dynamic-code-execution packages/sdk/src/mcp/tools.ts:125
MEDIUM js-dynamic-code-execution packages/sdk/src/page.ts:68
MEDIUM js-dynamic-code-execution packages/sdk/src/page.ts:73
MEDIUM sql-template-interpolation services/api/src/store/db.ts:116
MEDIUM js-dynamic-code-execution services/api/src/store/scanner.ts:44
MEDIUM sh-predictable-temp-path start.sh:25
LOW js-dynamic-code-execution apps/desktop/extensions/ai-sidebar/pit-proxy.test.js:8
LOW js-dynamic-code-execution packages/agent-runtime/src/analyze/form-script.test.ts:6
LOW js-unescaped-html-sink packages/agent-runtime/src/analyze/form-script.test.ts:26
LOW js-unescaped-html-sink packages/agent-runtime/src/analyze/form-script.test.ts:49
LOW js-dynamic-code-execution packages/browser-core/src/automation/extract-script.test.ts:6
LOW js-unescaped-html-sink packages/browser-core/src/automation/extract-script.test.ts:16
LOW js-unescaped-html-sink packages/browser-core/src/automation/extract-script.test.ts:45
LOW js-unescaped-html-sink packages/browser-core/src/automation/extract-script.test.ts:57
LOW js-unescaped-html-sink packages/browser-core/src/automation/extract-script.test.ts:80
LOW js-unescaped-html-sink packages/browser-core/src/automation/extract-script.test.ts:99
LOW js-dynamic-code-execution packages/browser-core/src/automation/snapshot-script.test.ts:11
LOW js-unescaped-html-sink packages/browser-core/src/automation/snapshot-script.test.ts:62
LOW js-unescaped-html-sink packages/browser-core/src/automation/snapshot-script.test.ts:101
LOW js-unescaped-html-sink packages/provenance/src/scan.test.ts:47
LOW js-unescaped-html-sink packages/provenance/src/scan.test.ts:170
LOW js-unescaped-html-sink packages/provenance/src/scan.test.ts:216
LOW js-dynamic-code-execution packages/sdk/src/mcp/automate.test.ts:261
LOW secret-generic-api-key packages/storage/src/config.ts:51
LOW secret-generic-credential packages/storage/src/config.ts:51

…and 2 more. Full results in the Security tab.

Snippets are redacted; ThreatCrush never prints matched credential material.

@ralyodio
ralyodio merged commit b4d1c33 into main Sep 24, 2026
7 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant