Skip to content

Tech Story: Add scheduled refresh token cleanup job #98

@GitAddRemote

Description

@GitAddRemote

Tech Story

As a platform engineer, I want expired and revoked refresh tokens periodically purged from the database so that the refresh_tokens table does not grow unboundedly and sensitive (even if hashed) token records are removed promptly after expiry.

Context

Refresh tokens are never deleted — only marked revoked = true or left with a past expiresAt. Over time this table accumulates every token ever issued. Beyond storage growth, retaining revoked/expired records longer than necessary increases the blast radius of a DB leak.

Acceptance Criteria

  • A scheduled job runs daily (configurable via env) and deletes all refresh_tokens rows where revoked = true OR expiresAt < NOW()
  • Job execution is logged (count of deleted rows, duration)
  • Job does not run in test environment (NODE_ENV === 'test')
  • Cleanup interval configurable via REFRESH_TOKEN_CLEANUP_CRON env var (default: 0 3 * * * — 3am daily)

Technical Elaboration

  • Create TokenCleanupService in the auth module decorated with @Injectable()
  • Use @Cron() from @nestjs/schedule (already installed) reading cron expression from ConfigService
  • Query: DELETE FROM refresh_tokens WHERE revoked = true OR expires_at < NOW()
  • Wrap in try/catch and log both success (rows deleted) and failure without rethrowing (job failure should not crash the process)
  • Register in AuthModule providers

Notes

  • ScheduleModule is already conditionally loaded in AppModule (skipped in test env) — no changes needed there
  • Consider adding a similar cleanup for password_resets table (used/expired rows)

Metadata

Metadata

Assignees

No one assigned

    Labels

    backendBackend services and logiccronjobsScheduled jobs and background tasksdatabaseSchema, migrations, indexingtech-storyTechnical implementation story

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions