Hey fellow devs! I recently tackled the challenge of building an authentication service for a microservices project. My priorities for v1 were speed and security, which led me down an interesting path: using an in-memory database.

Yeah, I know what you're thinking. "In-memory? For auth?" Bear with me.

Why In-Memory?

I wanted to validate the core authentication flow quickly, without getting bogged down by SQL or Redis setup. But this decision introduced a classic problem:

How do you securely bootstrap the initial admin user when your database is wiped on every restart?

Traditional approaches like migrations or environment variables felt brittle or insecure for this ephemeral setup. So, I looked at inspiration from tools like HashiCorp Vault and Grafana, and came up with my own twist.

🧠 The Idea: Secure, User-Triggered Bootstrap Token

Rather than automatically assigning an admin or relying on hardcoded tokens, I built a one-time, secure token-based bootstrap flow.

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚  Server Starts     β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
         β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ Generate One-Time Token  β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
         β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ Expose /v1/auth/bootstrap-admin    β”‚
β”‚ But only respond under conditions  β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

πŸš€ Flow Summary

  1. On server startup, a one-time bootstrap token is generated and stored in memory.
  2. The endpoint /v1/auth/bootstrap-admin checks if an admin already exists.
  3. If not, the first authenticated user to request it gets the token.
  4. That user uses the token to elevate themselves to admin via a protected endpoint.
  5. The token is invalidated and never reused.

πŸ” Detailed Breakdown

1. Server Startup:
   - Generates one-time bootstrap token
   - Keeps it in memory only

2. User Registers Normally:
   - Standard registration flow
   - Doesn't require bootstrap token

3. /v1/auth/bootstrap-admin (GET):
   - Authenticated user makes a request
   - If no admin exists β†’ returns token
   - If admin exists β†’ returns 403

4. /v1/admin/setup (POST):
   - User sends token in request
   - Server validates & promotes user to admin
   - Token is invalidated immediately

5. Future calls to /v1/auth/bootstrap-admin:
   - Always return 403

πŸ›‘οΈ Why RBAC Matters

This whole idea hinges on the fact that admin users have special privileges. That’s where Role-Based Access Control (RBAC) comes in.

I extended the user model to include a role field (e.g., "user", "admin"), and the JWTs include the role as a claim. Middleware checks that role before allowing access to protected endpoints.

User struct β†’ added role: string
JWT Claims β†’ added role
Middleware β†’ checks role per route

This ensures that only admins can manage users, elevate roles, or access sensitive endpoints.

πŸ”‘ Account Recovery: Planning for the Inevitable

Even in v1, I added a password reset flow using expiring reset tokens. This is essential β€” even for dev environments β€” to keep user flows realistic and secure.

🎯 Why This Approach Works

  • Secure: No hardcoded secrets or default admins.
  • Controlled: Only valid users can request the token.
  • Simple: Works across environments β€” local, CI, staging, etc.

πŸš€ Future Ideas

This bootstrap approach could later evolve into:

  • Database-backed setup tokens
  • Admin invitation flows
  • Secret rotation and better audits

πŸ’‘ Final Thoughts

This solution came from a desire to move fast without cutting corners on security. It's not a production pattern β€” and I wouldn’t recommend in-memory DBs for long-term auth β€” but for a study case or prototyping environment, it strikes the right balance.

Have you solved the "first-admin" problem differently? Used similar techniques? I'd love to hear your take!

Thanks for reading β€” and happy hacking! πŸ”