Skip to content

na-user User Management Microservice Overview

The na-user microservice is a simple solution for managing users, groups, and permission policies.

Virtually every online service needs to keep track of user data. The na-user microservice is a solution for the vast majority of those use cases. It allows your developers to focus on on your core business needs and avoid reinventing the wheel.

At its core na-user provides a simple REST API for maintaining a database of users and their commonly required metadata. You can add, delete, update, list, and search users, as well as assign them to groups and attach key/value data to their records.

In addition na-user is designed from the ground up to work in modern Kubernetes and Docker production environments. It is scalable, easy to deploy, and requires minimal administration overhead.

Features

  • Basics

    • Supports assigning users to groups and partitioning them by domain
    • Supports commonly associated user metadata such as contact information verification status, nicknames, birth dates, timezones, social media links and more
    • Set arbitrary key/value metadata on user records
    • Flexible user id creation, import your own or auto-create random, UUID, or ULID identifiers
    • Full Unicode UTF-8 support, including emoji
  • Dev-Ops

    • Packaged in a compact Docker container (a standalone daemon server is also available)
    • Configuration settings from environment variables or config file
    • Metrics endpoint for Prometheus integration
    • Health and liveliness endpoints for Kubernetes
    • Configurable HTTP server and database timeouts
    • Structured JSON logging, suitable for both auditing and debugging use cases
    • Default UTC log timestamps
  • Security

    • API access with HTTPS Basic Authentication over SSL
    • HTTPS API server default of TLS 1.3
    • Full TLS key/cert support for connecting to the database
    • Secret encryption with 256-bit AES-GCM with a random nonce
    • Paging result size configuration for security and performance
    • Audit friendly logging

System Architecture

Figure 1 below shows how the na-user service fits into a typical back end infrastructure design.

na-user Architecture Diagram

Figure 1. na-user Architectural Overview

The na-user service consists of one or more running na-user Docker containers and a dedicated user database. The database is provisioned by the customer who is responsible for its backup and availability.

User requests come in through the website's business logic, typically consisting of a load balancer or ingress controller and whatever site specific services are being provided.

Usually in modern deployments user authentication is done either by a cloud authentication service (e.g. Google Apple, Microsoft, Azure), or an on-premesis software such as Keycloak. Na-user can be used to securely store user passwords for typical userid/password authentication, though this is no longer recommended in favor of modern standards like Webauthn (FIDO) or OAuth.

Note that the na-user service can provide user state information to any authentication service via API, such as information on whether the user is banned or disabled.

At the end of authentication the business logic typically has some sort of user identifier like a username or UUID. This can then be passed to the na-user service to keep track of various customer information. The service is very flexible about what kind of user IDs it can accept or generate.

From then on na-user can be used to keep track of typical customer information accessible via API for any internal business logic. This can be usernames, email or postal addresses, screen names, timezones, language choices, social media links, verification status, activity timestamps, and so on.

Basically na-user abstracts the implementation of this sometimes complex user data infrastructure behind a simple JSON REST API.

Behind the API the na-user service takes care of the details of managing and validating user metadata, setting up the database tables, running efficient SQL queries, marshalling data to JSON, and dealing with errors.

na-user also plays nicely with modern Kubernetes environments by providing standard features such as metrics, health and liveliness endpoints, OpenTracing spans, secrets handling, and so on.

Authentication Architecture

na-user does not provide end user authentication directly. It is primarily meant to be used as a headless service, downstream from other internal services.

Services and administrators authenticate to na-user using basic HTTP authentication. Note that na-user fully supports the use of SSL/TLS both between services and in its connection to the database.

The recommended setup is to encrypt the link to na-user with SSL/TLS using certificates, and use basic authentication to authorize the API calls.

Note that in Kubernetes environments the network mesh may already encrypt inter-service communications, in which case setting up separate SSL certificates is not needed.

See the API Authentication section for details.

Scaling and High Availability

The simplest architectural use case is to have one na-user Docker container talking to one database. Scaling can then be done by simply adding resources to the virtual or real machine where the services are running.

Since the na-user container is stateless, scaling can also be done by increasing the number of the na-user containers and load balancing between them. Additionally scaling can be done by adding one or more database instances and using well known patterns such as read only replicas or partitioning traffic between multiple masters.

The ability to run multiple load balanced na-user containers leads naturally to high availability of the service. You can run multiple na-user containers and handle failover at the load balancer level. Alternatively if running under Kubernetes the system can be set up to respawn the na-user container should it fail.

To achieve high availability the backing database must also be set up appropriately, for example with multi master, failover, or disaster recovery features, a topic out of scoope for this guide.

Security

Data You Don't Have

User data is some of the most sensitive data a modern business posesses. The most secure data is data you don't have. The first line of defense is simply not to record any data you don't absolutely need. This is easy to do with na-user, because virtually all user data it deals with is optional. The minimal amount of information you need to use na-user is an opaque random userid. You can associate a wide variety of typical user information with that userid, but all of it is optional. Record only what you need.

Transport Security

The na-user API strives to be secure by design. The HTTP transport only supports SSL/TLS 1.3. It is expected that internal API calls to na-user will be protected by key and certificate files specified in the configuration. 1

Authentication

API authentication is done by using basic HTTP username/password authentication.

On first startup a secret password for the admin user is set via configuration file or environment variable. All subsequent API calls must use the admin/password combination to authenticate.

See the API Authentication section for details.

Encryption

The na-user server encrypts certain sensitive values.

The administrator password must be encrypted in the database to authenticate API calls against a password hash. na-user uses bcrypt with a default workfactor of 12 to generate and store password hashes. 2

Certain values such as paging tokens returned by the API must also be signed and encrypted using a configurable encryption secret. This secret is provided in a configuration file or via an environment variable. This secret is used to encrypt using a 256-bit AES-GCM cipher with a random nonce. Signatures use ECDSA curve P256.

IMPORTANT

If running multiple na-user containers it is important that all containers are configured with the same encryption secret, or funtionality such as paging will appear broken to API clients.

Data Encryption at Rest

Storing encrypted user data in the database is out of scope for na-user. However it is possible to use native database methods to store all data encrypted.

The following links discuss the options and limitations for data encryption at rest.



  1. Unencrypted HTTP access is configurable for legacy reasons but highly discouraged. It may be removed in the future. 

  2. The Bcrypt workfactor is configurable and may be adjusted to tune performance vs security tradeoffs. Lowering it is not recommended.