authorize: use jwt insead of state struct (#514)

authenticate: unmarshal and verify state from jwt, instead of middleware
authorize: embed opa policy using statik
authorize: have IsAuthorized handle authorization for all routes
authorize: if no signing key is provided, one is generated
authorize: remove IsAdmin grpc endpoint
authorize/client: return authorize decision struct
cmd/pomerium: main logger no longer contains email and group
cryptutil: add ECDSA signing methods
dashboard: have impersonate form show up for all users, but have api gated by authz
docs: fix typo in signed jwt header
encoding/jws: remove unused es256 signer
frontend: namespace static web assets
internal/sessions: remove leeway to match authz policy
proxy:  move signing functionality to authz
proxy: remove jwt attestation from proxy (authZ does now)
proxy: remove non-signed headers from headers
proxy: remove special handling of x-forwarded-host
sessions: do not verify state in middleware
sessions: remove leeway from state to match authz
sessions/{all}: store jwt directly instead of state

Signed-off-by: Bobby DeSimone <bobbydesimone@gmail.com>
This commit is contained in:
Bobby DeSimone 2020-03-10 11:19:26 -07:00 committed by GitHub
parent a477af9378
commit 8d1732582e
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
61 changed files with 1083 additions and 1264 deletions

View file

@ -163,7 +163,13 @@ func (m *IsAuthorizedRequest_Headers) GetValue() []string {
}
type IsAuthorizedReply struct {
IsValid bool `protobuf:"varint,1,opt,name=is_valid,json=isValid,proto3" json:"is_valid,omitempty"`
Allow bool `protobuf:"varint,1,opt,name=allow,proto3" json:"allow,omitempty"`
SessionExpired bool `protobuf:"varint,2,opt,name=session_expired,json=sessionExpired,proto3" json:"session_expired,omitempty"`
DenyReasons []string `protobuf:"bytes,3,rep,name=deny_reasons,json=denyReasons,proto3" json:"deny_reasons,omitempty"`
SignedJwt string `protobuf:"bytes,4,opt,name=signed_jwt,json=signedJwt,proto3" json:"signed_jwt,omitempty"`
User string `protobuf:"bytes,5,opt,name=user,proto3" json:"user,omitempty"`
Email string `protobuf:"bytes,6,opt,name=email,proto3" json:"email,omitempty"`
Groups []string `protobuf:"bytes,7,rep,name=groups,proto3" json:"groups,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
@ -194,89 +200,53 @@ func (m *IsAuthorizedReply) XXX_DiscardUnknown() {
var xxx_messageInfo_IsAuthorizedReply proto.InternalMessageInfo
func (m *IsAuthorizedReply) GetIsValid() bool {
func (m *IsAuthorizedReply) GetAllow() bool {
if m != nil {
return m.IsValid
return m.Allow
}
return false
}
type IsAdminRequest struct {
UserToken string `protobuf:"bytes,1,opt,name=user_token,json=userToken,proto3" json:"user_token,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *IsAdminRequest) Reset() { *m = IsAdminRequest{} }
func (m *IsAdminRequest) String() string { return proto.CompactTextString(m) }
func (*IsAdminRequest) ProtoMessage() {}
func (*IsAdminRequest) Descriptor() ([]byte, []int) {
return fileDescriptor_ffbc3c71370bee9a, []int{2}
}
func (m *IsAdminRequest) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_IsAdminRequest.Unmarshal(m, b)
}
func (m *IsAdminRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_IsAdminRequest.Marshal(b, m, deterministic)
}
func (m *IsAdminRequest) XXX_Merge(src proto.Message) {
xxx_messageInfo_IsAdminRequest.Merge(m, src)
}
func (m *IsAdminRequest) XXX_Size() int {
return xxx_messageInfo_IsAdminRequest.Size(m)
}
func (m *IsAdminRequest) XXX_DiscardUnknown() {
xxx_messageInfo_IsAdminRequest.DiscardUnknown(m)
}
var xxx_messageInfo_IsAdminRequest proto.InternalMessageInfo
func (m *IsAdminRequest) GetUserToken() string {
func (m *IsAuthorizedReply) GetSessionExpired() bool {
if m != nil {
return m.UserToken
return m.SessionExpired
}
return false
}
func (m *IsAuthorizedReply) GetDenyReasons() []string {
if m != nil {
return m.DenyReasons
}
return nil
}
func (m *IsAuthorizedReply) GetSignedJwt() string {
if m != nil {
return m.SignedJwt
}
return ""
}
type IsAdminReply struct {
IsValid bool `protobuf:"varint,1,opt,name=is_valid,json=isValid,proto3" json:"is_valid,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *IsAdminReply) Reset() { *m = IsAdminReply{} }
func (m *IsAdminReply) String() string { return proto.CompactTextString(m) }
func (*IsAdminReply) ProtoMessage() {}
func (*IsAdminReply) Descriptor() ([]byte, []int) {
return fileDescriptor_ffbc3c71370bee9a, []int{3}
}
func (m *IsAdminReply) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_IsAdminReply.Unmarshal(m, b)
}
func (m *IsAdminReply) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_IsAdminReply.Marshal(b, m, deterministic)
}
func (m *IsAdminReply) XXX_Merge(src proto.Message) {
xxx_messageInfo_IsAdminReply.Merge(m, src)
}
func (m *IsAdminReply) XXX_Size() int {
return xxx_messageInfo_IsAdminReply.Size(m)
}
func (m *IsAdminReply) XXX_DiscardUnknown() {
xxx_messageInfo_IsAdminReply.DiscardUnknown(m)
}
var xxx_messageInfo_IsAdminReply proto.InternalMessageInfo
func (m *IsAdminReply) GetIsValid() bool {
func (m *IsAuthorizedReply) GetUser() string {
if m != nil {
return m.IsValid
return m.User
}
return false
return ""
}
func (m *IsAuthorizedReply) GetEmail() string {
if m != nil {
return m.Email
}
return ""
}
func (m *IsAuthorizedReply) GetGroups() []string {
if m != nil {
return m.Groups
}
return nil
}
func init() {
@ -284,62 +254,63 @@ func init() {
proto.RegisterMapType((map[string]*IsAuthorizedRequest_Headers)(nil), "authorize.IsAuthorizedRequest.RequestHeadersEntry")
proto.RegisterType((*IsAuthorizedRequest_Headers)(nil), "authorize.IsAuthorizedRequest.Headers")
proto.RegisterType((*IsAuthorizedReply)(nil), "authorize.IsAuthorizedReply")
proto.RegisterType((*IsAdminRequest)(nil), "authorize.IsAdminRequest")
proto.RegisterType((*IsAdminReply)(nil), "authorize.IsAdminReply")
}
func init() { proto.RegisterFile("authorize.proto", fileDescriptor_ffbc3c71370bee9a) }
func init() {
proto.RegisterFile("authorize.proto", fileDescriptor_ffbc3c71370bee9a)
}
var fileDescriptor_ffbc3c71370bee9a = []byte{
// 390 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x8c, 0x93, 0xc1, 0x8e, 0xda, 0x30,
0x10, 0x86, 0x1b, 0x52, 0x08, 0x19, 0x28, 0x14, 0x53, 0xa9, 0x26, 0x6a, 0x0b, 0x8d, 0xd4, 0x8a,
0x5e, 0x52, 0x29, 0xbd, 0x54, 0x55, 0xa5, 0x8a, 0x43, 0x25, 0x38, 0xb4, 0x87, 0xa8, 0xed, 0xa5,
0x87, 0x28, 0x2b, 0x5b, 0xc2, 0x22, 0x60, 0xd6, 0x76, 0x90, 0xb2, 0xef, 0xb2, 0xef, 0xb7, 0x8f,
0xb1, 0x8a, 0xb1, 0xc3, 0xb2, 0x62, 0xd9, 0x3d, 0xe1, 0xf9, 0xe7, 0x9b, 0xdf, 0xe3, 0x5f, 0x04,
0xfa, 0x59, 0xa1, 0x96, 0x5c, 0xb0, 0x2b, 0x1a, 0x6d, 0x05, 0x57, 0x1c, 0xf9, 0xb5, 0x10, 0xde,
0xb8, 0x30, 0x5c, 0xc8, 0x99, 0xad, 0x49, 0x42, 0x2f, 0x0b, 0x2a, 0x15, 0x7a, 0x0b, 0x50, 0x48,
0x2a, 0x52, 0xc5, 0x57, 0x74, 0x83, 0x9d, 0x89, 0x33, 0xf5, 0x13, 0xbf, 0x52, 0xfe, 0x54, 0x02,
0xfa, 0x00, 0x3d, 0xb1, 0x27, 0xd3, 0x35, 0x55, 0x4b, 0x4e, 0x70, 0x43, 0x23, 0x2f, 0x8c, 0xfa,
0x4b, 0x8b, 0x68, 0x0c, 0x1d, 0x8b, 0x15, 0x22, 0xc7, 0xae, 0x66, 0xc0, 0x48, 0x7f, 0x45, 0x8e,
0xde, 0x43, 0xd7, 0x02, 0x4b, 0x2e, 0x15, 0x7e, 0xae, 0x09, 0x3b, 0x34, 0xe7, 0x52, 0xa1, 0x08,
0x86, 0x16, 0x39, 0x78, 0x31, 0xdc, 0xd4, 0xe4, 0xc0, 0x48, 0x89, 0xb5, 0x64, 0xc7, 0xfc, 0x9a,
0x2b, 0x9a, 0x66, 0x84, 0x08, 0xdc, 0xba, 0xc7, 0x57, 0x9d, 0x19, 0x21, 0x02, 0xfd, 0x87, 0x7e,
0xbd, 0x02, 0xcd, 0x08, 0x15, 0x12, 0x7b, 0x13, 0x77, 0xda, 0x89, 0xe3, 0xe8, 0x90, 0xdb, 0x89,
0x88, 0x22, 0xf3, 0x3b, 0xdf, 0x0f, 0xfd, 0xdc, 0x28, 0x51, 0x26, 0x36, 0x15, 0x23, 0x06, 0x63,
0xf0, 0xcc, 0x11, 0xbd, 0x82, 0xe6, 0x2e, 0xcb, 0x0b, 0x8a, 0x9d, 0x89, 0x3b, 0xf5, 0x93, 0x7d,
0x11, 0x30, 0x18, 0x9e, 0xf0, 0x41, 0x2f, 0xc1, 0x5d, 0xd1, 0xd2, 0xe4, 0x5e, 0x1d, 0xd1, 0x77,
0x3b, 0x5e, 0x05, 0xdd, 0x89, 0x3f, 0x3e, 0xb2, 0x9c, 0x71, 0x33, 0xd7, 0x7c, 0x6b, 0x7c, 0x75,
0xc2, 0x08, 0x06, 0xc7, 0xe4, 0x36, 0x2f, 0xd1, 0x08, 0xda, 0x4c, 0xa6, 0xbb, 0x2c, 0x67, 0x44,
0xdf, 0xd6, 0x4e, 0x3c, 0x26, 0xff, 0x55, 0x65, 0xf8, 0x19, 0x7a, 0x0b, 0x39, 0x23, 0x6b, 0xb6,
0x79, 0xda, 0x9f, 0x22, 0xfc, 0x04, 0xdd, 0x7a, 0xe0, 0xbc, 0x77, 0x7c, 0xed, 0x00, 0xd4, 0xab,
0x08, 0xf4, 0x5b, 0x4f, 0xd6, 0xab, 0xa1, 0x77, 0xe7, 0x5f, 0x17, 0xbc, 0x79, 0xb0, 0xbf, 0xcd,
0xcb, 0xf0, 0x19, 0xfa, 0x01, 0x9e, 0xd9, 0x04, 0x8d, 0x8e, 0xd1, 0x3b, 0xcf, 0x09, 0x5e, 0x9f,
0x6a, 0x69, 0x83, 0x8b, 0x96, 0xfe, 0x50, 0xbe, 0xdc, 0x06, 0x00, 0x00, 0xff, 0xff, 0x72, 0x3a,
0xa3, 0xe0, 0x3b, 0x03, 0x00, 0x00,
// 431 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x84, 0x93, 0xcf, 0x6e, 0x13, 0x31,
0x10, 0xc6, 0xd9, 0x6e, 0x9b, 0x76, 0x27, 0xa5, 0xa1, 0x13, 0x84, 0xac, 0x08, 0x68, 0x88, 0x04,
0xe4, 0x94, 0x43, 0xb8, 0x20, 0xc4, 0xa5, 0x87, 0x4a, 0x05, 0x09, 0x0e, 0x16, 0x9c, 0x40, 0x5a,
0x2d, 0xf2, 0xa8, 0x59, 0xea, 0xac, 0x17, 0xdb, 0x4b, 0x58, 0x1e, 0x94, 0x67, 0xe0, 0x31, 0x90,
0xff, 0xa5, 0x14, 0x15, 0x38, 0xad, 0xe7, 0xe7, 0xcf, 0xe3, 0x99, 0xf9, 0xbc, 0x30, 0xaa, 0x3a,
0xbb, 0x52, 0xba, 0xfe, 0x4e, 0x8b, 0x56, 0x2b, 0xab, 0xb0, 0xd8, 0x82, 0xd9, 0xcf, 0x1c, 0xc6,
0xaf, 0xcc, 0x69, 0x8a, 0x05, 0xa7, 0x2f, 0x1d, 0x19, 0x8b, 0x0f, 0x00, 0x3a, 0x43, 0xba, 0xb4,
0xea, 0x92, 0x1a, 0x96, 0x4d, 0xb3, 0x79, 0xc1, 0x0b, 0x47, 0xde, 0x39, 0x80, 0x8f, 0xe1, 0x48,
0x07, 0x65, 0xb9, 0x26, 0xbb, 0x52, 0x82, 0xed, 0x78, 0xc9, 0xed, 0x48, 0xdf, 0x78, 0x88, 0x27,
0x30, 0x4c, 0xb2, 0x4e, 0x4b, 0x96, 0x7b, 0x0d, 0x44, 0xf4, 0x5e, 0x4b, 0x7c, 0x04, 0x87, 0x49,
0xb0, 0x52, 0xc6, 0xb2, 0x5d, 0xaf, 0x48, 0x87, 0xce, 0x95, 0xb1, 0xb8, 0x80, 0x71, 0x92, 0x5c,
0xe5, 0xaa, 0xd9, 0x9e, 0x57, 0x1e, 0x47, 0xc4, 0x53, 0xca, 0xfa, 0xba, 0x7e, 0xad, 0x2c, 0x95,
0x95, 0x10, 0x9a, 0x0d, 0xfe, 0xd0, 0xbb, 0x9d, 0x53, 0x21, 0x34, 0x7e, 0x80, 0xd1, 0xb6, 0x04,
0xaa, 0x04, 0x69, 0xc3, 0xf6, 0xa7, 0xf9, 0x7c, 0xb8, 0x5c, 0x2e, 0xae, 0xe6, 0x76, 0xc3, 0x88,
0x16, 0xf1, 0x7b, 0x1e, 0x0e, 0x9d, 0x35, 0x56, 0xf7, 0x3c, 0x4d, 0x25, 0xc2, 0xc9, 0x09, 0xec,
0xc7, 0x25, 0xde, 0x85, 0xbd, 0xaf, 0x95, 0xec, 0x88, 0x65, 0xd3, 0x7c, 0x5e, 0xf0, 0x10, 0x4c,
0x6a, 0x18, 0xdf, 0x90, 0x07, 0xef, 0x40, 0x7e, 0x49, 0x7d, 0x9c, 0xbb, 0x5b, 0xe2, 0xcb, 0x74,
0xdc, 0x0d, 0x7a, 0xb8, 0x7c, 0xf2, 0x9f, 0xe2, 0x62, 0xb6, 0x78, 0xcd, 0x8b, 0x9d, 0xe7, 0xd9,
0xec, 0x47, 0x06, 0xc7, 0xd7, 0xa5, 0xad, 0xec, 0x5d, 0x59, 0x95, 0x94, 0x6a, 0xe3, 0xef, 0x3a,
0xe0, 0x21, 0xc0, 0xa7, 0x30, 0x32, 0x64, 0x4c, 0xad, 0x9a, 0x92, 0xbe, 0xb5, 0xb5, 0xa6, 0x60,
0xf0, 0x01, 0x3f, 0x8a, 0xf8, 0x2c, 0x50, 0x67, 0xa0, 0xa0, 0xa6, 0x2f, 0x35, 0x55, 0x46, 0x35,
0x86, 0xe5, 0xbe, 0xb9, 0xa1, 0x63, 0x3c, 0x20, 0xf7, 0x94, 0x4c, 0x7d, 0xd1, 0x90, 0x28, 0x3f,
0x6f, 0x92, 0xc3, 0x45, 0x20, 0xaf, 0x37, 0x16, 0x11, 0x76, 0xdd, 0xbb, 0x8a, 0x86, 0xfa, 0xb5,
0x2b, 0x8a, 0xd6, 0x55, 0x2d, 0xa3, 0x6b, 0x21, 0xc0, 0x7b, 0x30, 0xb8, 0xd0, 0xaa, 0x6b, 0x83,
0x41, 0x05, 0x8f, 0xd1, 0xf2, 0x23, 0xc0, 0xb6, 0x2b, 0x8d, 0x6f, 0xe1, 0xf0, 0xf7, 0x2e, 0xf1,
0xe1, 0xbf, 0x27, 0x35, 0xb9, 0xff, 0xd7, 0xfd, 0x56, 0xf6, 0xb3, 0x5b, 0x9f, 0x06, 0xfe, 0x9f,
0x79, 0xf6, 0x2b, 0x00, 0x00, 0xff, 0xff, 0x8b, 0x10, 0x59, 0xee, 0x46, 0x03, 0x00, 0x00,
}
// Reference imports to suppress errors if they are not otherwise used.
var _ context.Context
var _ grpc.ClientConn
var _ grpc.ClientConnInterface
// This is a compile-time assertion to ensure that this generated file
// is compatible with the grpc package it is being compiled against.
const _ = grpc.SupportPackageIsVersion4
const _ = grpc.SupportPackageIsVersion6
// AuthorizerClient is the client API for Authorizer service.
//
// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream.
type AuthorizerClient interface {
IsAuthorized(ctx context.Context, in *IsAuthorizedRequest, opts ...grpc.CallOption) (*IsAuthorizedReply, error)
IsAdmin(ctx context.Context, in *IsAdminRequest, opts ...grpc.CallOption) (*IsAdminReply, error)
}
type authorizerClient struct {
cc *grpc.ClientConn
cc grpc.ClientConnInterface
}
func NewAuthorizerClient(cc *grpc.ClientConn) AuthorizerClient {
func NewAuthorizerClient(cc grpc.ClientConnInterface) AuthorizerClient {
return &authorizerClient{cc}
}
@ -352,19 +323,9 @@ func (c *authorizerClient) IsAuthorized(ctx context.Context, in *IsAuthorizedReq
return out, nil
}
func (c *authorizerClient) IsAdmin(ctx context.Context, in *IsAdminRequest, opts ...grpc.CallOption) (*IsAdminReply, error) {
out := new(IsAdminReply)
err := c.cc.Invoke(ctx, "/authorize.Authorizer/IsAdmin", in, out, opts...)
if err != nil {
return nil, err
}
return out, nil
}
// AuthorizerServer is the server API for Authorizer service.
type AuthorizerServer interface {
IsAuthorized(context.Context, *IsAuthorizedRequest) (*IsAuthorizedReply, error)
IsAdmin(context.Context, *IsAdminRequest) (*IsAdminReply, error)
}
// UnimplementedAuthorizerServer can be embedded to have forward compatible implementations.
@ -374,9 +335,6 @@ type UnimplementedAuthorizerServer struct {
func (*UnimplementedAuthorizerServer) IsAuthorized(ctx context.Context, req *IsAuthorizedRequest) (*IsAuthorizedReply, error) {
return nil, status.Errorf(codes.Unimplemented, "method IsAuthorized not implemented")
}
func (*UnimplementedAuthorizerServer) IsAdmin(ctx context.Context, req *IsAdminRequest) (*IsAdminReply, error) {
return nil, status.Errorf(codes.Unimplemented, "method IsAdmin not implemented")
}
func RegisterAuthorizerServer(s *grpc.Server, srv AuthorizerServer) {
s.RegisterService(&_Authorizer_serviceDesc, srv)
@ -400,24 +358,6 @@ func _Authorizer_IsAuthorized_Handler(srv interface{}, ctx context.Context, dec
return interceptor(ctx, in, info, handler)
}
func _Authorizer_IsAdmin_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(IsAdminRequest)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(AuthorizerServer).IsAdmin(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: "/authorize.Authorizer/IsAdmin",
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(AuthorizerServer).IsAdmin(ctx, req.(*IsAdminRequest))
}
return interceptor(ctx, in, info, handler)
}
var _Authorizer_serviceDesc = grpc.ServiceDesc{
ServiceName: "authorize.Authorizer",
HandlerType: (*AuthorizerServer)(nil),
@ -426,10 +366,6 @@ var _Authorizer_serviceDesc = grpc.ServiceDesc{
MethodName: "IsAuthorized",
Handler: _Authorizer_IsAuthorized_Handler,
},
{
MethodName: "IsAdmin",
Handler: _Authorizer_IsAdmin_Handler,
},
},
Streams: []grpc.StreamDesc{},
Metadata: "authorize.proto",