The quiet failure mode of a shared integration
Most SaaS products that integrate with Google register one OAuth app, server-wide, and every customer's Calendar or Drive calls go through it. That works fine until usage grows — Google's API quotas are per-app, not per-customer, so one organization running an unusually chatty sync can eat into the headroom every other organization on the platform depends on. Nobody notices until a completely unrelated tenant's calendar sync starts failing for a reason that has nothing to do with anything they did.
WKFGo's answer: your own app, your own quota
// Package orgcreds stores per-organization OAuth app credentials, so every
// tenant brings its own third-party app (its own Google Cloud project, …)
// instead of sharing one server-wide app from the environment. Org admins
// manage them in the UI (/integrations); integrations resolve credentials
// per-org at call time and fall back to the server env only when the org has
// none — self-hosted single-tenant installs keep working unchanged.
Each organization can register its own Google Cloud project and plug its client ID and secret into Integrations in WKFGo. From that point on, every Calendar and Drive call that organization makes runs against its own quota, under its own Google Cloud billing if it exceeds the free tier — completely isolated from every other organization on the same WKFGo instance.
What's stored, and how it's protected
type OrgCredential struct {
OrganizationID uint
Provider string // "google" — covers Calendar + Drive
ClientID string
ClientSecret string `json:"-"` // encrypted
UpdatedBy uint
}
The client secret is encrypted at rest before it touches the database, under a purpose-scoped key (orgcreds), and it's tagged json:"-" so it never comes back out through any API response once it's saved — the UI that manages it can update it, but can't read it back. One provider covers both Calendar and Drive because Google issues a single OAuth app per Cloud project regardless of how many of its APIs you enable.
The fallback that keeps self-hosting simple
func Lookup(db *gorm.DB, orgID uint, provider string) (clientID, clientSecret string, ok bool) {
// returns the org's decrypted credentials; ok is false when the org has none
}
If an organization hasn't registered its own app, Lookup returns ok = false and the calling code falls back to a server-wide credential from the environment. That's not a half-measure — it's the deliberate design for the common self-hosted case: one company, one instance, no reason to force a per-org OAuth app when the "org" and "the deployment" are the same thing. Multi-tenant cloud deployments are where per-org credentials actually matter, and that's exactly where an org admin would go set them up.
Setting up your own Google Cloud project
1. Create a Google Cloud project (or reuse one you already have) and enable the Calendar API.
2. Configure the OAuth consent screen with your organization's name — this is what your own team sees on the Google permission prompt, not a generic third-party app name.
3. Create OAuth 2.0 credentials and add WKFGo's redirect URI as an authorized redirect.
4. Paste the client ID and secret into Integrations in WKFGo. From here, Google Calendar sync uses your app, not a shared one.
Common mistakes
Assuming this is required to use Calendar sync at all. It isn't — the fallback to a server-side credential exists precisely so a small team doesn't need to touch Google Cloud Console just to try the feature. Registering your own app matters once usage or compliance requirements make a shared quota or a shared app identity a problem.
Restricting the OAuth consent screen to internal users only, then wondering why the connection fails. If your Cloud project's consent screen is set to "Internal," only accounts inside your own Google Workspace can authorize it — fine if that's everyone using WKFGo, a source of confusing failures if it isn't.
Rotating the secret in Google Cloud without updating it in WKFGo. The two have to be updated together; WKFGo has no way to detect that a secret was rotated on Google's side until the next API call fails.
FAQ
Does this cost anything beyond WKFGo's subscription? Google's Calendar and Drive APIs have a generous free tier that most organizations never exceed; you'd only see a Google Cloud bill under unusually heavy API usage.
Can different organizations on the same WKFGo instance use different Google Workspace domains? Yes — each organization's OAuth app is entirely independent, so this is exactly the case per-org credentials are built for.
What happens to existing calendar links if I switch from the fallback app to my own? Existing event links keep working; new sync calls start using your app's quota going forward.