Those are the things that bite.
Security is not about mystique. It is about staying recoverable in the worst case.
What this means for multi-tenant Actor design
Once you accept "client_id is visible by design", the architecture gets cleaner. Attention naturally shifts to:
-
scope minimization â request only the permissions you truly need (in my Actor,
gmail.readonly and nothing else)
-
explicit token lifecycle â when it renews, when it expires, when it can be revoked
-
auditable execution path â which tenant triggered which run when
These decisions directly affect product trust and how much firefighting future-you will be doing.
Self-host does not exempt you from threat modeling
A tempting shortcut: "It's self-host, so the risk lives with the user."
That is half right. Yes, deployment responsibility moves to the operator. But as the author you still owe secure defaults:
- safe defaults rather than risky defaults
- explicit documentation rather than verbal hints
- observable errors rather than silent failures
Otherwise you are not reducing risk, you are just shifting it.
Documentation pattern
For OAuth-touching repos, I now write three things first:
- Which values are public, which must stay private
- The lifecycle and revocation path for every token
- What a user can actually do when an authorization error happens
Two effects:
- new users do not get blocked on a panic about the wrong thing
- experienced reviewers can audit your security logic quickly
The clearer you are, the easier it is for the community to trust your project.
Open-source carries extra weight
In open source, a misleading security narrative is more dangerous than in a private product, because it gets copied.
If you frame client_id as "top secret", others will copy that posture and ship the same broken model with real problems intact.
I prefer to spell it out in the README:
-
client_id is expected to be visible
- the real sensitive surface is token handling and flow protection
- multi-tenant isolation is enforced through data structure and routing logic
That way, even a fork carries a less-wrong threat model forward.
Closing: stop asking "can I hide it"
The question I keep on a sticky note for OAuth design is:
"If this value gets seen, is the system still safe?"
If a single exposed value collapses the system, the problem is not secret management â it is brittle architecture.
For Gmail OAuth in a self-host Actor, client_id is not the protagonist. The real protagonist is a verifiable, revocable, isolated authorization system.
Related
Source: foxck016077/apify-gmail-inbox-intel — MIT, why OAuth client IDs are public by design, plus self-host actor hardening notes for real deployments.
Discussion question: What misconception about OAuth client IDs do you see most often in self-hosted setups, and how do you correct it in docs?
📊 Cold-start update (4 days in): 7 articles, 1 star, 0 sales, 4 days — what an MIT open-source Apify Actor cold start actually looks like — design notes only matter if the cold-start mechanics deliver readers. The follow-up post has the actual traffic numbers.
Update (May 19): The Actor that uses this pattern is live: apify.com/foxck/gmail-inbox-intel — free MIT, paste 3 OAuth fields (client_id is in the public input schema as documented above), get stalled threads ranked. Companion PDF now pay-what-you-want from 1ドル.
Day 7 update (later May 19): I shipped a product pivot — the Gumroad listing above is now a Self-Host Bundle for engineers (full Actor source + docker-compose.yml + 5-min OAuth setup), PWYW from 5ドル suggested 19ドル. The original PDF still ships inside as a bonus. Same URL.
Day 7 write-up with the funnel audit that triggered the pivot: funnel audit found 7 of 9 articles had no buy link, then I pivoted the product.
Sample report preview: Friday Triage gist — anonymized 10-thread example of the 99ドル Done-For-You triage output. Grounded in r/sales 1tdngew (49 comments on re-engaging cold prospects) and r/smallbusiness 1td0827 (60-comment thread, top reply at 61 score: "holding 50 open loops in your head").
More from the shop:
Read the latest checkpoint: Day 16 — +51 reader spike in 85 min, 0 sales
Day 18 — pbot v1 dev preview shipped
After 18 days of this ZERO-TEN cold start: 9ドル PDF killed at Day 17, pivoted to pbot — a one-click personal knowledge bot you install on your own machine. Talk to it from LINE / Telegram / Zalo on your phone.
v1 dev preview is real: 93 MB macOS .dmg packaged, 15k-chunk SQLite FTS5 queries in 0-3 ms, Anthropic real calls with source citations, daemon auto-start on boot. Day 18 deep dive: the 7-line bigram fix for Chinese search.
Join the pbot waitlist (29ドル · first-100 get -30% → 20ドル) →