FAQ & Summary
Once the Shadow-User pattern is in place, the questions that follow are nearly always the same: what happens when the IdP is down, whether the local foreign keys survive, when to call out for an authorization decision versus reading a claim. This page answers those directly, then closes the course with the principles worth remembering.
Frequently asked questions
Section titled “Frequently asked questions”Can I skip the shadow table and store the user ID as plain text everywhere?
Section titled “Can I skip the shadow table and store the user ID as plain text everywhere?”You can — that is the Federated-IDs archetype from Four Integration Archetypes. The cost is losing database JOINs and cascade deletes against a real user row. That trade is worth it for microservices, where services do not share a database anyway, but not for a foreign-key-heavy monolith like the Hono template.
My Hono app has eight tables with foreign keys to users. Do I rewrite all of them?
Section titled “My Hono app has eight tables with foreign keys to users. Do I rewrite all of them?”No — keep them. The shadow table’s id is the same shape (varchar(255)) as before,
and the shadow row carries the same ID as Auther’s source-of-truth user. The existing
foreign keys still resolve because nothing about the ID changed.
What about social logins like Google or GitHub?
Section titled “What about social logins like Google or GitHub?”Configure the social providers in Auther’s auth.ts. Auther’s OIDC flow handles the
provider hop transparently, so your Hono server only ever sees an ordinary Auther JWT.
From the app’s side there is no difference between a password login and a social one.
Can I keep my own custom signup form?
Section titled “Can I keep my own custom signup form?”Yes. Proxy the sign-up through Hono to Auther’s sign-up endpoint, authenticating the
call with the x-internal-signup-secret header. Auther’s registration contexts then
handle any post-signup permission grants, so the new account lands with the right
relationships already in place.
What happens if Auther is down?
Section titled “What happens if Auther is down?”Most of the system keeps working, because verification is local:
- Existing JWTs keep validating — you cache the JWKS, so no live call is needed.
- New logins fail, since they require Auther’s authorization endpoint.
- Token refresh fails once an access token expires.
- The
/check-permissioncall fails. Your app decides the posture: fail-closed (safe) or fail-open for static permissions (risky). - Webhooks queue in QStash and deliver once Auther is back.
For higher availability, the typical pattern is multi-region Auther behind a load balancer with the JWKS served from a CDN.
Can I issue my own JWTs from Hono, signed with Auther’s keys?
Section titled “Can I issue my own JWTs from Hono, signed with Auther’s keys?”No. The private signing keys are encrypted at rest in Auther’s database and never leave it — your app can only verify, never sign. When you need service-to-service tokens, use Auther’s API key exchange flow to mint them instead.
My JWT is too big because I belong to many tenants. How do I shrink it?
Section titled “My JWT is too big because I belong to many tenants. How do I shrink it?”Include only the active tenant’s permissions, built by Auther’s token_build
pipeline. Switching tenants then becomes a token re-issue rather than a single bloated
token carrying every tenant’s claims at once.
Should I sync access.granted and access.revoked events into auth_relations?
Section titled “Should I sync access.granted and access.revoked events into auth_relations?”Only if you need local admin queries such as “list every user with admin on org X.”
For enforcement you do not need the sync at all: the JWT claim is the source of truth
at token-issuance time, and reading it is cheaper than querying a mirrored table.
When should I call Auther’s /check-permission versus deciding locally?
Section titled “When should I call Auther’s /check-permission versus deciding locally?”Ask one question: does the permission depend on the resource’s runtime attributes —
its amount, status, or ownership? If yes, it is an ABAC decision and belongs in an
Auther /check-permission call. If no, a local check or a JWT claim is enough. Most
permissions fall into the latter group.
Can a user have multiple sessions on multiple devices?
Section titled “Can a user have multiple sessions on multiple devices?”Yes. Auther issues an independent token per session, and your Hono server treats each request the same way: a valid JWT from this user. Devices do not need to coordinate.
How do I force logout everywhere?
Section titled “How do I force logout everywhere?”Revoke all of the user’s sessions in Auther’s admin UI. Already-issued JWTs remain
valid until their exp, so revocation is not instant by default. When you need
immediate cutoff, maintain a jti deny-list and reject revoked token IDs at the edge.
Do I really keep packages/authorization?
Section titled “Do I really keep packages/authorization?”Yes — it is the recommended default. Your local authorization package is good at app-domain permissions, while Auther’s authorization handles identity-level concerns. The two coexist and both run at request time; neither replaces the other.
Two authorization systems feels wrong. Can I fully delegate to Auther?
Section titled “Two authorization systems feels wrong. Can I fully delegate to Auther?”Yes, and it is a valid choice. Move every resource and permission into Auther’s
authorization models, delete packages/authorization, and always resolve access
through JWT claims plus Auther’s /check-permission. The architecture is simpler and
there is a single place to manage policy — at the cost of more latency on the ABAC
paths.
What to remember
Section titled “What to remember”If you carry nine things away from integrating Auther into an app that already owns its data, make it these:
That closes the integration course. You now have a per-column ownership model, the Shadow-User pattern, a file-by-file Hono walkthrough, the end-to-end flows, and a catalog of edge cases — enough to land a centralized identity provider into a real codebase without a multi-week rewrite.