Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

JWT based authentication support #6

Closed
wants to merge 6 commits into from

Conversation

t-chaik
Copy link

@t-chaik t-chaik commented Mar 4, 2019

This series of patch introduce JWT based authentication support for the min gRPC endpoint:

  • Server-side TLS support for the main gRPC endpoint:
    • CLI configuration interface.
  • Client-side TLS support for the "grpc" blobstore backend:
  • JWT authentication for the main gRPC endpoint:
    • JWT token extraction and validation.
    • JWT token validation caching.
    • CLI configuration interface.

Suggestion on better naming for API, CLI and configuration are very welcome.

Copy link
Member

@EdSchouten EdSchouten left a comment

Choose a reason for hiding this comment

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

Hi Martin,

Don't be discouraged by any of my remarks. Those changes look pretty neat already. Thanks for working on this! \o/

cmd/bb_storage/main.go Outdated Show resolved Hide resolved
cmd/bb_storage/main.go Outdated Show resolved Hide resolved
pkg/proto/blobstore/blobstore.proto Outdated Show resolved Hide resolved
pkg/blobstore/configuration/create_blob_access.go Outdated Show resolved Hide resolved
pkg/proto/blobstore/blobstore.proto Outdated Show resolved Hide resolved
pkg/blobstore/configuration/create_blob_access.go Outdated Show resolved Hide resolved
pkg/auth/jwt.go Outdated Show resolved Hide resolved
@t-chaik
Copy link
Author

t-chaik commented Mar 4, 2019

Don't be discouraged by any of my remarks. Those changes look pretty neat already. Thanks for working on this! \o/

No problem, I submitted that WIP precisely to get these remarks! Has you may know, I'm very new to Go so any comments are more than welcome.

@t-chaik t-chaik force-pushed the mablanch/2-auth-support branch 3 times, most recently from c488028 to c1b5cd0 Compare March 8, 2019 15:43
@t-chaik t-chaik changed the title WIP: JWT based authentication support JWT based authentication support Mar 8, 2019
Copy link
Member

@EdSchouten EdSchouten left a comment

Choose a reason for hiding this comment

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

Thanks a lot! The patch looks pretty good already. Let's go for the icing on the cake. 👍

cmd/bb_storage/main.go Outdated Show resolved Hide resolved
cmd/bb_storage/main.go Outdated Show resolved Hide resolved
cmd/bb_storage/main.go Outdated Show resolved Hide resolved
pkg/auth/jwt_auth_cache.go Outdated Show resolved Hide resolved
pkg/auth/jwt_auth_cache.go Outdated Show resolved Hide resolved
pkg/auth/jwt_auth_cache.go Outdated Show resolved Hide resolved
pkg/auth/jwt_auth_cache.go Outdated Show resolved Hide resolved
pkg/blobstore/configuration/create_blob_access.go Outdated Show resolved Hide resolved
pkg/blobstore/grpc_metadata_forwarding_blob_access.go Outdated Show resolved Hide resolved
pkg/proto/blobstore/blobstore.proto Outdated Show resolved Hide resolved
Secured mode can be activated and configured through the CLI.
@t-chaik t-chaik force-pushed the mablanch/2-auth-support branch 3 times, most recently from 5c59308 to 614d066 Compare March 12, 2019 10:46
@t-chaik
Copy link
Author

t-chaik commented Mar 15, 2019

@EdSchouten: I've added basic unit tests for the JWT auth. validator. How does that all look to you now?

pkg/auth/jwt_auth_cache.go Show resolved Hide resolved
pkg/auth/jwt_auth_cache.go Outdated Show resolved Hide resolved
pkg/auth/jwt_auth_cache.go Outdated Show resolved Hide resolved
pkg/auth/jwt_auth_cache_test.go Outdated Show resolved Hide resolved
pkg/util/options.go Outdated Show resolved Hide resolved
pkg/util/options.go Outdated Show resolved Hide resolved
pkg/auth/jwt_auth_cache.go Outdated Show resolved Hide resolved
pkg/auth/jwt_auth_cache_test.go Show resolved Hide resolved
pkg/blobstore/configuration/create_blob_access.go Outdated Show resolved Hide resolved
Martin Blanchard added 4 commits March 18, 2019 10:11
TLS connection details can be specified in the blobstore configuration.
Authenticated mode can be activated and configured through the CLI.
Forwarding client context allows for authorization credentials to be
forwarded along to be remote service.
@mickael-carl
Copy link
Member

Hi there! Mind rebasing your PR off master? Then we can merge this!

@prestonvanloon
Copy link

Any update on this? Authentication seems like a hard requirement for many deployments of buildbarn.

@EdSchouten
Copy link
Member

@t-chaik is unfortunately no longer contributing to this project, which is why this PR never made any further progress. Fortunately, some progress has been made on this in the meantime. gRPC servers can nowadays be configured to use an authenticator:

// Policy for authenticating clients against the gRPC server.
AuthenticationPolicy authentication_policy = 4;
// Maximum size of a Protobuf message that may be received by this
// server.
int64 maximum_received_message_size_bytes = 5;
}
message AuthenticationPolicy {
oneof policy {
// Allow all incoming requests.
google.protobuf.Empty allow = 1;
// Allow incoming requests if one of multiple authentication
// policies allows it, similar to Python's any() function.
AnyAuthenticationPolicy any = 2;
// Deny all incoming requests, returning a fixed error message back
// to the client.
string deny = 3;
// Allow incoming requests in case they present a valid TLS
// certificate.
TLSClientCertificateAuthenticationPolicy tls_client_certificate = 4;
}
}
message AnyAuthenticationPolicy {
// Set of backing authentication policies.
repeated AuthenticationPolicy policies = 1;
}
message TLSClientCertificateAuthenticationPolicy {
// PEM data for the certificate authorities that should be used to
// validate the remote TLS client.
string client_certificate_authorities = 1;
}

// Authenticator can be used to grant or deny access to a gRPC server.
// Implementations may grant access based on TLS connection state,
// provided headers, source IP address ranges, etc. etc. etc.
type Authenticator interface {
Authenticate(ctx context.Context) error
}
// NewAuthenticatorFromConfiguration creates a tree of Authenticator
// objects based on a configuration file.
func NewAuthenticatorFromConfiguration(policy *configuration.AuthenticationPolicy) (Authenticator, error) {
if policy == nil {
return nil, status.Error(codes.InvalidArgument, "Authentication policy not specified")
}
switch policyKind := policy.Policy.(type) {
case *configuration.AuthenticationPolicy_Allow:
return AllowAuthenticator, nil
case *configuration.AuthenticationPolicy_Any:
children := make([]Authenticator, 0, len(policyKind.Any.Policies))
for _, childConfiguration := range policyKind.Any.Policies {
child, err := NewAuthenticatorFromConfiguration(childConfiguration)
if err != nil {
return nil, err
}
children = append(children, child)
}
return NewAnyAuthenticator(children), nil
case *configuration.AuthenticationPolicy_Deny:
return NewDenyAuthenticator(policyKind.Deny), nil
case *configuration.AuthenticationPolicy_TlsClientCertificate:
clientCAs := x509.NewCertPool()
if !clientCAs.AppendCertsFromPEM([]byte(policyKind.TlsClientCertificate.ClientCertificateAuthorities)) {
return nil, status.Error(codes.InvalidArgument, "Failed to parse client certificate authorities")
}
return NewTLSClientCertificateAuthenticator(
clientCAs,
clock.SystemClock), nil
default:
return nil, status.Error(codes.InvalidArgument, "Configuration did not contain an authentication policy type")
}
}

There are a couple of basic ones: always allow, always deny, TLS client certificate validation and an any() function that you can use to chain multiple authenticators. All that now needs to be done is that someone steps up and adds one that validates JWTs, or uses OAuth2, etc..

It now makes sense to work on this, because Bazel finally gained support for properly passing in credentials: bazelbuild/bazel#10015 bazelbuild/bazel#10634

@prestonvanloon
Copy link

Awesome! Just two days ago :)

My project just got setup with RBE and are looking to use buildbarn for our CI pipeline. I'd love to be able to expose a public endpoint for my team to make authenticated build requests. How can I help? Does bb-storage need support for jwt/oauth2/etc or is it already good to go with the latest bazel and some flag configuration?

@EdSchouten
Copy link
Member

EdSchouten commented Mar 5, 2020

Awesome! Just two days ago :)

My project just got setup with RBE and are looking to use buildbarn for our CI pipeline. I'd love to be able to expose a public endpoint for my team to make authenticated build requests. How can I help? Does bb-storage need support for jwt/oauth2/etc or is it already good to go with the latest bazel and some flag configuration?

You should be able to get it all working by doing this:

  1. Ensure you're using Bazel master.
  2. Call Bazel with --remote_executor=grpcs://hostname:port --remote_header=authorization="Bearer some-oauth2-access-key-or-jwt-goes-here"
  3. You will need to set up bb-storage, but you'll have to patch it up to add a new implementation of Authenticator that validates the token. You'll be able to extract the token from within the Authenticator by calling metadata.FromIncomingContext(ctx).Get("authorization").

@EdSchouten
Copy link
Member

Let’s close this specific PR, as the author will likely not update this.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants