When you host ForgeHub with us, your instance connects to services that are yours,
not ours — your GitHub, your S3 bucket, your email sender. A hosting platform
should never put its own credentials inside your application, and it should never
ask you to guess which ones yours needs.
We got the first half right by accident and the second half wrong by omission.
## What your instance actually receives
A provisioned instance gets exactly five values from us:
- its application ID
- a signed entitlement document describing your plan
- the key to verify that document, derived per instance
- the single-sign-on issuer
- the SSO secret, also derived per instance
That is the whole list. Our Stripe keys, our mail credentials, our cloud
credentials — none of them are forwarded, and none of them can be, because nothing
in the provisioning path reads them. Two instances cannot reach each other's
secrets because neither holds anything shared.
That isolation was correct. The problem was the consequence.
## Twenty-three keys, all undefined
ForgeHub reads seventeen integration credentials — GitHub, S3 and AWS, email,
Google, browser push. In a real instance every single one was `undefined`.
And the settings pages *told* you so, without offering anywhere to fix it. The
payment page read the environment, reported "not configured", and its Save button
persisted exactly one field: your currency. Storage did the same. They looked
editable. They were status displays.
You could set these variables — through the control panel's environment editor,
which writes to your instance and restarts it. That worked the whole time. But
nothing anywhere told you ForgeHub wanted `RESEND_API_KEY` or `VAPID_PRIVATE_KEY`.
A capability nobody can discover is not a feature.
## Settings → Integrations
Your instance now stores its own credentials, in its own database, encrypted with
AES-256-GCM. Five integrations, each explaining plainly what it enables and **what
breaks without it** — because "not configured" is useless next to "no email leaves
this instance, so nobody is notified of approvals".
Three details worth stating:
**We cannot show you a key back.** Once saved, the interface returns only the last
four characters. Replacing means typing a new one. There is no read path, for us or
for you.
**A Test button that makes a real call.** Each integration runs the cheapest
authenticated read its provider offers — a bucket `HEAD`, a token check, a domain
list. Nothing is created, sent or deleted. It reports the provider's own message,
because "invalid api key" and "bucket does not exist" send you to different fixes,
and collapsing both into "test failed" wastes your afternoon. Before this, a
mistyped key failed at the moment it first mattered, while the page still showed a
confident tick.
**You cannot break your own instance from this page.** Writes are restricted to the
seventeen keys that belong to you. Platform values — the database URL, the
authentication secret, our per-instance derived keys — are refused. That last one
matters more than it looks: the authentication secret is what your stored
credentials are encrypted with.
## What we deliberately left out
**SMTP.** ForgeHub's SMTP sender is an unimplemented stub that logs a warning and
discards the message. We could have shipped a full SMTP form; it would have been a
setup flow that appears to succeed and delivers nothing. That is the same class of
bug as the dialog in our first post, and we are not adding a second one. Email runs
through Resend until the transport is real.
**Stripe.** You will own your Stripe keys eventually, for invoicing your own
clients. We have not settled how that interacts with our billing yet, so rather
than ship a half-answer it is absent, and says so.
## Why this delayed us
None of this was on the roadmap. It came out of asking a narrow question — what
does a real instance actually receive? — and finding that the honest answer was
"five values and no way to add more".
We would rather find that ourselves than have you find it on day three, holding an
instance that cannot send an email and a settings page that shrugs.
Enjoyed this article?
Subscribe for more insights on DevOps, security, and developer tools. No spam, unsubscribe anytime.