Skip to content

authn: add Redis KV backend for multi-replica AuthN#307

Open
Rohithmatham12 wants to merge 2 commits into
NVIDIA:mainfrom
Rohithmatham12:authn-kv-service-config
Open

authn: add Redis KV backend for multi-replica AuthN#307
Rohithmatham12 wants to merge 2 commits into
NVIDIA:mainfrom
Rohithmatham12:authn-kv-service-config

Conversation

@Rohithmatham12

@Rohithmatham12 Rohithmatham12 commented Jun 9, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Add generic auth.db.service config plus AIS_AUTHN_KV_* environment overrides for external AuthN KV services.
  • Add a Redis-backed AuthN KV driver selected with auth.db.type = "Redis"; local BuntDB remains the default backend.
  • Share the same collection/key layout across BuntDB and Redis via kvdb.MakePath.
  • Add Redis driver coverage with miniredis for set/get/delete/list/get-all/delete-collection behavior.
  • Document Redis-based shared AuthN storage for multi-replica deployments and add third-party notices for the new Redis-related dependencies.

Closes #273.

Testing

  • gofmt -w api/env/authn.go api/authn/config.go api/authn/config_internal_test.go cmd/authn/config/cmgr.go cmd/authn/config/cmgr_test.go cmd/authn/kvdb/kvdb.go cmd/authn/kvdb/redis.go cmd/authn/kvdb/redis_internal_test.go cmn/kvdb/api.go cmn/kvdb/bunt.go
  • go test ./api/authn ./cmd/authn/config ./cmd/authn/kvdb ./cmd/authn/signing ./cmn/kvdb
  • go test ./cmd/authn
  • git diff --check

Signed-off-by: Rohithmatham12 <rohithmatham@gmail.com>
@Rohithmatham12 Rohithmatham12 force-pushed the authn-kv-service-config branch from 9cd1259 to 5d3799d Compare June 9, 2026 02:59
@Rohithmatham12 Rohithmatham12 changed the title authn: add generic KV service config authn: add Redis KV backend for multi-replica AuthN Jun 9, 2026
@aaronnw aaronnw self-requested a review June 9, 2026 21:07

@aaronnw aaronnw left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for opening! I left some comment on the implementation, will look at the go mod additions and licensing separately.

Comment thread api/authn/config.go Outdated
defaultPort = 52001
defaultTokenExpiration = cos.Duration(24 * time.Hour)
defaultMaxTokenAge = cos.Duration(90 * 24 * time.Hour)
defaultKVServiceAddr = "localhost:6379"

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's split port away from address.

Comment thread api/env/authn.go Outdated
AisAuthKVAddr = "AIS_AUTHN_KV_ADDR" // external KV service address for AuthN DB backends
AisAuthKVPassword = "AIS_AUTHN_KV_PASSWORD" // optional external KV service password
AisAuthKVDBIndex = "AIS_AUTHN_KV_DB_INDEX" // optional external KV service database/index
AisAuthKVTLS = "AIS_AUTHN_KV_TLS" // optional TLS toggle for external KV service

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think we should support env var overrides for any of these except maybe password. We can expect the config contains everything we need to configure DB access.

Comment thread api/authn/config.go Outdated
}
KVServiceConf struct {
Addr string `json:"addr,omitempty"`
Password string `json:"password,omitempty"` //nolint:gosec // configuration field, not a hardcoded credential

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For password, I think we should not need to put it in config. If we do, we need to use cmn.Censored and use json:"-" similar to ServerConf.psecret`.

But I would question if there's any value in having it if we do not persist it. I would expect for real deployments we'll use k8s env from secret or vault injection.

Comment thread api/authn/config.go Outdated
if c.Service.DBIndex < 0 {
return fmt.Errorf("invalid auth.db.service.db_index=%d (must be >= 0)", c.Service.DBIndex)
}
if c.DBType == "Redis" && c.Service.Addr == "" {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can this be a typed enum like BuntDB in kvdb.go?

Comment thread cmd/authn/kvdb/redis.go Outdated
for _, path := range batch {
val, err := r.client.Get(context.Background(), path).Result()
if err != nil {
if err == redis.Nil {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

prefer errors.Is()

Comment thread cmd/authn/kvdb/redis.go
Addr: conf.Addr,
Password: conf.Password,
DB: conf.DBIndex,
}

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe for the cancel context created below to work we need ContextTimeoutEnabled in the driver options here.

Comment thread cmd/authn/kvdb/redis.go Outdated
opts.TLSConfig = &tls.Config{MinVersion: tls.VersionTLS12}
}
client := redis.NewClient(opts)
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this timeout would be a valid addition to KVServiceConf

Comment thread cmd/authn/kvdb/redis.go
}
client := redis.NewClient(opts)
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think all calls below that are using context.Background should instead do a similar wrap, e.g.:

func (r *redisDriver) SetString(collection, key, data string) (int, error) {
	ctx, cancel := r.ctx()
	defer cancel()
	if err := r.client.Set(ctx, kvdb.MakePath(collection, key), data, 0).Err(); err != nil {
		return http.StatusInternalServerError, err
	}
	return http.StatusOK, nil
}

and use a common ctx() func to define a context.WithTimeout(context.Background(), r.timeout)

For multi-step operations like GetAll, then re-use the same context across all calls.

@Rohithmatham12

Copy link
Copy Markdown
Contributor Author

Updated the PR to address the Redis KV review feedback:

  • split Redis service configuration into host and port
  • removed KV env overrides except AIS_AUTHN_KV_PASSWORD
  • kept the Redis password out of persisted config and inject it only at runtime
  • changed auth.db.type to typed AuthN DB driver values
  • added auth.db.service.timeout and wired Redis operations through per-operation timeout contexts
  • enabled Redis ContextTimeoutEnabled and switched Redis nil checks to errors.Is
  • updated Redis/config tests and AuthN docs for the new config shape

Validation run locally:

  • go test ./api/authn ./cmd/authn/config ./cmd/authn/kvdb ./cmd/authn/signing ./cmn/kvdb
  • go test ./cmd/authn
  • git diff --check

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Support for multi-replica AuthN deployments

2 participants