Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions api/client/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -3495,6 +3495,18 @@ func (c *Client) DeleteAllIntegrations(ctx context.Context) error {
return trail.FromGRPC(err)
}

// GenerateAWSOIDCToken generates a token to be used when executing an AWS OIDC Integration action.
func (c *Client) GenerateAWSOIDCToken(ctx context.Context, req types.GenerateAWSOIDCTokenRequest) (string, error) {
resp, err := c.integrationsClient().GenerateAWSOIDCToken(ctx, &integrationpb.GenerateAWSOIDCTokenRequest{
Issuer: req.Issuer,
})
if err != nil {
return "", trail.FromGRPC(err)
}

return resp.GetToken(), nil
}

// PluginsClient returns an unadorned Plugins client, using the underlying
// Auth gRPC connection.
// Clients connecting to non-Enterprise clusters, or older Teleport versions,
Expand Down
282 changes: 213 additions & 69 deletions api/gen/proto/go/teleport/integration/v1/integration_service.pb.go

Large diffs are not rendered by default.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

17 changes: 17 additions & 0 deletions api/proto/teleport/integration/v1/integration_service.proto
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,9 @@ service IntegrationService {

// DeleteAllIntegrations removes all Integrations.
rpc DeleteAllIntegrations(DeleteAllIntegrationsRequest) returns (google.protobuf.Empty);

// GenerateAWSOIDCToken generates a token to be used when executing an AWS OIDC Integration action.
rpc GenerateAWSOIDCToken(GenerateAWSOIDCTokenRequest) returns (GenerateAWSOIDCTokenResponse);
}

// ListIntegrationsRequest is a request for a paginated list of Integrations.
Expand Down Expand Up @@ -86,3 +89,17 @@ message DeleteIntegrationRequest {

// DeleteAllIntegrationsRequest is the request for deleting all integrations.
message DeleteAllIntegrationsRequest {}

// GenerateAWSOIDCTokenRequest are the parameters used to request an AWS OIDC
// Integration token.
message GenerateAWSOIDCTokenRequest {
// Issuer is the entity that is signing the JWT.
// This value must contain the AWS OIDC Integration configured provider (Teleport Proxy's Public URL)
string issuer = 1;
}

// GenerateAWSOIDCTokenResponse contains a signed AWS OIDC Integration token.
message GenerateAWSOIDCTokenResponse {
// Token is the signed JWT ready to be used
string token = 1;
}
43 changes: 43 additions & 0 deletions api/types/integration_awsoidc.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
/*
Copyright 2023 Gravitational, Inc.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package types

import "github.com/gravitational/trace"

const (
// IntegrationAWSOIDCAudience is the client id used to generate the JWT.
// This value must match the Audience defined in the IAM Identity Provider of the Integration.
IntegrationAWSOIDCAudience = "discover.teleport"

// IntegrationAWSOIDCSubject identifies the system that is going to use the token.
IntegrationAWSOIDCSubject = "system:proxy"
)

// GenerateAWSOIDCTokenRequest are the parameters used to request an AWS OIDC Integration token.
type GenerateAWSOIDCTokenRequest struct {
// Issuer is the entity that is signing the JWT.
// This value must contain the AWS OIDC Integration configured provider (Proxy's Public URL).
Issuer string `json:"issuer"`
}
Comment on lines 29 to 34
Copy link
Copy Markdown
Contributor

@kimlisa kimlisa Apr 18, 2023

Choose a reason for hiding this comment

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

i'm confused why this type is necessary? can't we use the pb type from the get go? this is what i see in other places, so i am not sure which method/pattern to stick with (or what makes this one the exception)

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I did it only to implement the CheckAndSetDefaults
The pb type is created here: api/gen/proto/go/teleport/integration/v1/integration_service.pb.go
I was trying to avoid adding custom code close in those auto generated folders.


// CheckAndSetDefaults checks if the required fields are present.
func (req *GenerateAWSOIDCTokenRequest) CheckAndSetDefaults() error {
if req.Issuer == "" {
return trace.BadParameter("issuer is required")
}

return nil
}
42 changes: 42 additions & 0 deletions api/types/integration_awsoidc_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
/*
Copyright 2023 Gravitational, Inc.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package types

import (
"testing"

"github.com/gravitational/trace"
"github.com/stretchr/testify/require"
)

// TestGenerateAWSOIDCTokenRequest validates that the required fields are checked.
func TestGenerateAWSOIDCTokenRequest(t *testing.T) {
t.Run("error when no issuer is provided", func(t *testing.T) {
req := GenerateAWSOIDCTokenRequest{}

err := req.CheckAndSetDefaults()
require.True(t, trace.IsBadParameter(err), "expected a bad parameter error, got %+v", err)
})

t.Run("success when issuer is provided", func(t *testing.T) {
req := GenerateAWSOIDCTokenRequest{
Issuer: "https://example.com",
}

err := req.CheckAndSetDefaults()
require.NoError(t, err)
})
}
8 changes: 6 additions & 2 deletions api/types/trust.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,10 +47,14 @@ const (
// SAMLIDPCA identifies the certificate authority that will be used by the
// SAML identity provider.
SAMLIDPCA CertAuthType = "saml_idp"
// OIDCIdPCA (OpenID Connect Identity Provider Certificate Authority) identifies
// the certificate authority that will be used by the OIDC Identity Provider.
// Similar to JWTSigner, it doesn't issue Certificates but signs JSON Web Tokens.
OIDCIdPCA CertAuthType = "oidc_idp"
)

// CertAuthTypes lists all certificate authority types.
var CertAuthTypes = []CertAuthType{HostCA, UserCA, DatabaseCA, OpenSSHCA, JWTSigner, SAMLIDPCA}
var CertAuthTypes = []CertAuthType{HostCA, UserCA, DatabaseCA, OpenSSHCA, JWTSigner, SAMLIDPCA, OIDCIdPCA}

// NewlyAdded should return true for CA types that were added in the current
// major version, so that we can avoid erroring out when a potentially older
Expand All @@ -64,7 +68,7 @@ func (c CertAuthType) addedInMajorVer() int64 {
switch c {
case DatabaseCA:
return 9
case OpenSSHCA, SAMLIDPCA:
case OpenSSHCA, SAMLIDPCA, OIDCIdPCA:
return 12
default:
// We don't care about other CAs added before v4.0.0
Expand Down
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ require (
github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.11.62
github.com/aws/aws-sdk-go-v2/service/athena v1.25.0
github.com/aws/aws-sdk-go-v2/service/ec2 v1.93.2
github.com/aws/aws-sdk-go-v2/service/rds v1.42.3
github.com/aws/aws-sdk-go-v2/service/s3 v1.31.3
github.com/aws/aws-sdk-go-v2/service/sns v1.20.8
github.com/aws/aws-sdk-go-v2/service/sts v1.18.9
Expand Down
2 changes: 2 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -205,6 +205,8 @@ github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.9.26 h1:uUt4XctZL
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.9.26/go.mod h1:Bd4C/4PkVGubtNe5iMXu5BNnaBi/9t/UsFspPt4ram8=
github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.14.1 h1:lRWp3bNu5wy0X3a8GS42JvZFlv++AKsMdzEnoiVJrkg=
github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.14.1/go.mod h1:VXBHSxdN46bsJrkniN68psSwbyBKsazQfU2yX/iSDso=
github.com/aws/aws-sdk-go-v2/service/rds v1.42.3 h1:6fwUZilITdPTrgPn2rLz8sF9/GhSjrwKR/ys8K/xvUk=
github.com/aws/aws-sdk-go-v2/service/rds v1.42.3/go.mod h1:MsNKuqHhTJrmI6A0TBdhSYiQ7SYkKncIWRIp9KfzRfs=
github.com/aws/aws-sdk-go-v2/service/s3 v1.31.3 h1:MG+2UlhyBL3oCOoHbUQh+Sqr3elN0I5PBe0MtVh0xMg=
github.com/aws/aws-sdk-go-v2/service/s3 v1.31.3/go.mod h1:aSl9/LJltSz1cVusiR/Mu8tvI4Sv/5w/WWrJmmkNii0=
github.com/aws/aws-sdk-go-v2/service/sns v1.20.8 h1:wy1jYAot40/Odzpzeq9S3OfSddJJ5RmpaKujvj5Hz7k=
Expand Down
2 changes: 1 addition & 1 deletion lib/auth/auth.go
Original file line number Diff line number Diff line change
Expand Up @@ -4988,7 +4988,7 @@ func newKeySet(ctx context.Context, keyStore *keystore.Manager, caID types.CertA
return keySet, trace.Wrap(err)
}
keySet.SSH = append(keySet.SSH, sshKeyPair)
case types.JWTSigner:
case types.JWTSigner, types.OIDCIdPCA:
jwtKeyPair, err := keyStore.NewJWTKeyPair(ctx)
if err != nil {
return keySet, trace.Wrap(err)
Expand Down
21 changes: 21 additions & 0 deletions lib/auth/auth_with_roles.go
Original file line number Diff line number Diff line change
Expand Up @@ -421,6 +421,27 @@ func (a *ServerWithRoles) DeleteIntegration(ctx context.Context, name string) er
return trace.Wrap(err)
}

// GenerateAWSOIDCToken generates a token to be used when executing an AWS OIDC Integration action.
func (a *ServerWithRoles) GenerateAWSOIDCToken(ctx context.Context, req types.GenerateAWSOIDCTokenRequest) (string, error) {
igSvc, err := a.integrationsService()
if err != nil {
return "", trace.Wrap(err)
}

if err := req.CheckAndSetDefaults(); err != nil {
return "", trace.Wrap(err)
}

resp, err := igSvc.GenerateAWSOIDCToken(ctx, &integrationpb.GenerateAWSOIDCTokenRequest{
Issuer: req.Issuer,
})
if err != nil {
return "", trace.Wrap(err)
}

return resp.Token, nil
}

// CreateSessionTracker creates a tracker resource for an active session.
func (a *ServerWithRoles) CreateSessionTracker(ctx context.Context, tracker types.SessionTracker) (types.SessionTracker, error) {
if err := a.serverAction(); err != nil {
Expand Down
3 changes: 3 additions & 0 deletions lib/auth/clt.go
Original file line number Diff line number Diff line change
Expand Up @@ -799,6 +799,9 @@ type ClientI interface {
// Implements ReadAccessPoint.
GetWebToken(ctx context.Context, req types.GetWebTokenRequest) (types.WebToken, error)

// GenerateAWSOIDCToken generates a token to be used to execute an AWS OIDC Integration action.
GenerateAWSOIDCToken(ctx context.Context, req types.GenerateAWSOIDCTokenRequest) (string, error)

// ResetAuthPreference resets cluster auth preference to defaults.
ResetAuthPreference(ctx context.Context) error

Expand Down
2 changes: 2 additions & 0 deletions lib/auth/grpcserver.go
Original file line number Diff line number Diff line change
Expand Up @@ -5078,6 +5078,8 @@ func NewGRPCServer(cfg GRPCServerConfig) (*GRPCServer, error) {
Authorizer: cfg.Authorizer,
Backend: cfg.AuthServer.Services,
Cache: cfg.AuthServer.Cache,
Clock: cfg.AuthServer.clock,
CAGetter: cfg.AuthServer,
})
if err != nil {
return nil, trace.Wrap(err)
Expand Down
2 changes: 1 addition & 1 deletion lib/auth/init.go
Original file line number Diff line number Diff line change
Expand Up @@ -676,7 +676,7 @@ func checkResourceConsistency(ctx context.Context, keyStore *keystore.Manager, c
_, signerErr = keyStore.GetSSHSigner(ctx, r)
case types.DatabaseCA, types.SAMLIDPCA:
_, _, signerErr = keyStore.GetTLSCertAndSigner(ctx, r)
case types.JWTSigner:
case types.JWTSigner, types.OIDCIdPCA:
_, signerErr = keyStore.GetJWTSigner(ctx, r)
default:
return trace.BadParameter("unexpected cert_authority type %s for cluster %v", r.GetType(), clusterName)
Expand Down
Loading