Oauth define at buildtime
Skill kjuhwa/skills-hub/skills/electron/oauth-define-at-buildtime
Self-correcting knowledge corpus for Claude Code — 9 stable shape clusters, bias-correction pipeline baked into contribution flow. 47 papers, 45 techniques, 1.1k skills.
npx -y skills add kjuhwa/skills-hub --skill oauth-define-at-buildtimeAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
One thing to look at
- 0 stars0 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.
What its author says it does
Copied from the file, not written here
Bake OAuth client IDs/secrets into the main-process bundle at build time via esbuild --define:process.env.X=... so they ship with the app, while user-provided secrets (Google) stay out of the build.
SKILL.md
3.3 KB, 705 tokens by cl100k_base, as published. Nobody here has run it
Bake OAuth config at build time
When to use
- Your Electron app integrates with OAuth providers (Slack, Microsoft, Sentry) that require a client ID/secret baked into the app at distribution time.
- Some providers (Google) forbid embedding credentials in public code; users must supply their own.
- You want
process.env.SLACK_OAUTH_CLIENT_IDto resolve to the literal value in the packaged bundle without leaking in the repo.
How it works
.env.examplelists the variables;.env(gitignored) holds real values, or CI provides them as secrets.- Build script reads
.envintoprocess.env. - Enumerate the variables to define:
const definedVars = ['SLACK_OAUTH_CLIENT_ID', 'SLACK_OAUTH_CLIENT_SECRET', 'MICROSOFT_OAUTH_CLIENT_ID', 'MICROSOFT_OAUTH_CLIENT_SECRET', 'SENTRY_ELECTRON_INGEST_URL']; - Build
esbuild --define:process.env.X="value"flags from those vars:const defines = definedVars.map(v => `--define:process.env.${v}="${process.env[v] ?? ''}"`); - Pass through
spawn(['bun', 'run', 'esbuild', ..., ...defines])when bundlingmain.cjs. - At runtime in packaged code,
process.env.SLACK_OAUTH_CLIENT_IDis a literal string the minifier already inlined. - Explicitly document that Google OAuth is NOT baked in - users fill it in via source config. Provide a setup guide.
- For local
electron:devdevelopment,.envis loaded at runtime so devs can iterate without rebuilding.
Example
// Build script
function loadEnvFile() {
const content = readFileSync(join(ROOT, '.env'), 'utf8');
for (const line of content.split('\n')) {
if (line.startsWith('#') || !line.includes('=')) continue;
const [k, ...rest] = line.split('='); process.env[k] = rest.join('=').trim();
}
}
loadEnvFile();
const defines = ['SLACK_OAUTH_CLIENT_ID','SLACK_OAUTH_CLIENT_SECRET','MICROSOFT_OAUTH_CLIENT_ID']
.map(v => `--define:process.env.${v}="${process.env[v] ?? ''}"`);
spawn({ cmd: ['bun', 'run', 'esbuild', 'src/main/index.ts', '--bundle', ...defines], /*...*/ });
Gotchas
- Anything in a public build is in the hands of every user - don't bake admin-level secrets. Client IDs + OAuth secrets are fine per OAuth RFCs for desktop clients.
- Use
""notundefinedfor missing values - an unquotedundefinedis invalid JS and will crash the bundle. - CI builds need the same env vars as local; use GitHub Actions
secrets.SLACK_OAUTH_CLIENT_ID->env: SLACK_OAUTH_CLIENT_ID: ${{ secrets.X }}. - Google specifically refuses to let third-party apps embed their client secret. Surface this to users early.
- esbuild's
--definesubstitutes literal text; wrap the value in quotes so it's a JS string, not an identifier.