Source Print Discuss
🔰 Final Standard

PIP-20: Basic Authentication for gRPC APIs


Authors Javad Rajabzadeh (@Ja7ad)
Discussion View Discussion PIP-20
Category Interface
Created 14-01-2024

Abstract #

This proposal aims to enhance the security of gRPC APIs by implementing a Basic Authentication mechanism. The goal is to provide a simple yet effective way to authenticate clients accessing the APIs.

Motivation #

Security is paramount in modern systems, and implementing a reliable authentication mechanism is essential to safeguard sensitive data and resources. Basic Authentication offers a straightforward approach to validate client credentials and control access to gRPC services.

Specification #

The proposed authentication enhancement involves implementing a middleware component within the gRPC server to handle Basic Authentication. The middleware will intercept incoming requests, validate the provided credentials, and allow or deny access based on the authentication outcome.

Generate Password Hash #

  1. Generate Bcrypt Hash:

Bcrypt is a widely used hashing algorithm for securely hashing passwords. It includes a salt to protect against rainbow table attacks and is computationally intensive to slow down brute-force attempts. Various methods, including the htpasswd command-line tool, can be used to generate a bcrypt-hashed password. The general syntax for htpasswd is:

htpasswd -bnB <username> <password>
  • b: Use batch mode to retrieve the password from the command line rather than prompting for it.
  • n: Display the results on standard output.
  • B: Force the use of the bcrypt algorithm.
  • username: The username for which the password is being generated.
  • password: The password to be hashed.

For example:

htpasswd -bnB foo bar

This command outputs the bcrypt-hashed password for the user “foo”.

  1. Store the Hashed Password in Configuration File:

Once the bcrypt-hashed password is obtained, it can be stored in the configuration file:

[grpc]
  enable = true
  listen = "[::]:50052"
  basic_auth = "foo:$2y$05$3DdFhI74T5PwNyxFdh9wiOttWZCzmVEcI2GoTfNh4b1YubZgyZadS"

Basic Authentication Middleware #

The Basic Authentication middleware operates as follows:

  1. Extract the Authorization header from incoming requests.
  2. Decode the Base64-encoded username and password from the header.
  3. Validate the credentials against the predefined username and hashed password stored in the configuration.
  4. Allow access to the endpoint for valid credentials or reject the request with an appropriate error message for invalid or missing credentials.

Example Middleware Implementation #

func BasicAuthInterceptor(username, password string) grpc.ServerOption {
  return grpc.UnaryInterceptor(func(ctx context.Context, req interface{},
    info *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (interface{}, error) {

    // Extract Authorization header from the context
    authHeader, ok := metadata.FromIncomingContext(ctx)
    if !ok {
      return nil, status.Error(codes.Unauthenticated, "Missing authentication credentials")
    }

    // Extract and decode username and password from the Authorization header
    // Perform Basic Authentication
    // If authentication fails, return an Unauthenticated error
    // If authentication succeeds, proceed to the next handler
  })
}

Rationale #

Basic Authentication provides a simple yet effective way to control access to gRPC APIs. It is widely supported by client libraries and can be easily integrated into existing systems without significant overhead.

Backward Compatibility #

This proposal ensures backward compatibility by allowing existing implementations to retain their authentication method configurations. The Basic Authentication method can be selectively enabled for specific APIs or endpoints without impacting the overall system behavior.

References #


Copyright

Copyright and related rights waived via CC0.