Skip to content

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.

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.

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.

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-permission call 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.

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.

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.

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.