Skip to content
This repository has been archived by the owner on Oct 14, 2024. It is now read-only.

Commit

Permalink
feat: cleanup and simplify iam provider
Browse files Browse the repository at this point in the history
  • Loading branch information
ramizpolic committed Jul 26, 2023
1 parent 40f6a55 commit dfd8578
Show file tree
Hide file tree
Showing 4 changed files with 29 additions and 32 deletions.
8 changes: 4 additions & 4 deletions backend/pkg/backend/backend.go
Original file line number Diff line number Diff line change
Expand Up @@ -83,15 +83,15 @@ func Run(ctx context.Context) {
go database.CreateDemoData(ctx, dbHandler)
}

// Create IAM injector
iamInjector, err := iam.NewOIDCInjector(config.OIDC.Issuer, config.OrchestratorKeyPath, config.OIDC.GetScopes())
// Create auth injector
authInjector, err := iam.NewOIDCAuthInjectorFromKey(config.OIDC.Issuer, config.OrchestratorKeyPath, config.OIDC.GetScopes())
if err != nil {
logger.Fatalf("Failed to create IAM injector: %v", err)
logger.Fatalf("Failed to create auth injector: %v", err)
}

// Create API client
backendAddress := fmt.Sprintf("http://%s%s", net.JoinHostPort(config.BackendRestHost, strconv.Itoa(config.BackendRestPort)), rest.BaseURL)
backendClient, err := backendclient.Create(backendAddress, client.WithRequestEditorFn(iamInjector.Inject))
backendClient, err := backendclient.Create(backendAddress, client.WithRequestEditorFn(authInjector))
if err != nil {
logger.Fatalf("Failed to create a backend client: %v", err)
}
Expand Down
8 changes: 3 additions & 5 deletions backend/pkg/iam/iam.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,13 +45,11 @@ type User struct {
Roles map[string]bool `json:"roles"`
}

// Injector implements client-side authentication data injection.
type Injector interface {
Inject(ctx context.Context, request *http.Request) error
}

// Provider implements server-side IAM synchronization policy.
type Provider interface {
// Authenticate validates and verifies user auth details from request against
// some auth provider. It should also be able to fetch permissions associated
// with that key from some location.
Authenticate(ctx context.Context, request *http.Request) (*User, error)
}

Expand Down
42 changes: 22 additions & 20 deletions backend/pkg/iam/oidc.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ package iam
import (
"context"
"fmt"
"github.com/openclarity/vmclarity/api/client"
"github.com/openclarity/vmclarity/backend/pkg/config"
"github.com/zitadel/oidc/pkg/client/rs"
"github.com/zitadel/oidc/pkg/oidc"
Expand All @@ -35,6 +36,9 @@ type oidcProvider struct {
// NewOIDCProvider creates a Provider which intercepts requests and checks for a
// correct Bearer token using OAuth2 introspection by sending the token to the
// introspection endpoint.
//
// TODO: Enable support for creating ResourceServer for file data from string.
// TODO: This can be achieved using functional options, e.g. WithKey().
func NewOIDCProvider(config config.OIDC) (Provider, error) {
// Add custom OIDC options
var options []rs.Option
Expand Down Expand Up @@ -64,6 +68,8 @@ func NewOIDCProvider(config config.OIDC) (Provider, error) {
}

func (provider *oidcProvider) Authenticate(ctx context.Context, request *http.Request) (*User, error) {
// TODO: Explore caching options to reduce checks against identity server

// Validate authorization header
authHeader := request.Header.Get("Authorization")
if authHeader == "" {
Expand Down Expand Up @@ -106,36 +112,32 @@ func (provider *oidcProvider) Authenticate(ctx context.Context, request *http.Re
}, nil
}

type oidcInjector struct {
tokenSource oauth2.TokenSource
}

// NewOIDCInjector creates an Injector which creates OAuth2 token source from key
// file to generate tokens that are injected in requests.
func NewOIDCInjector(issuer, keyPath string, scopes []string) (Injector, error) {
// NewOIDCAuthInjectorFromKey creates a client injector which creates OAuth2 token
// source from key file to generate tokens that are injected in requests.
//
// TODO: Add support for injectors from file data string and Personal Access Tokens

Check failure on line 118 in backend/pkg/iam/oidc.go

View workflow job for this annotation

GitHub Actions / Verification

Comment should end in a period (godot)
func NewOIDCAuthInjectorFromKey(issuer, keyPath string, scopes []string) (client.RequestEditorFn, error) {
// Get token source and token
tokenSource, err := middleware.JWTProfileFromPath(keyPath)(issuer, append(scopes, oidc.ScopeOpenID))
if err != nil {
return nil, fmt.Errorf("unable to create OIDC token source: %w", err)
}

token, err := tokenSource.Token()
if err != nil {
return nil, fmt.Errorf("unable to fetch OIDC token: %w", err)
}

// Return Injector with reusable token source to prevent request spikes
return &oidcInjector{
tokenSource: oauth2.ReuseTokenSource(token, tokenSource),
}, nil
}
// Use reusable token source to prevent request spikes
tokenSource = oauth2.ReuseTokenSource(token, tokenSource)

func (injector *oidcInjector) Inject(_ context.Context, request *http.Request) error {
token, err := injector.tokenSource.Token()
if err != nil {
return err
}
// Return client token injector function
return func(_ context.Context, request *http.Request) error {
token, err := tokenSource.Token()
if err != nil {
return err

Check failure on line 137 in backend/pkg/iam/oidc.go

View workflow job for this annotation

GitHub Actions / Verification

error returned from interface method should be wrapped: sig: func (golang.org/x/oauth2.TokenSource).Token() (*golang.org/x/oauth2.Token, error) (wrapcheck)
}

token.SetAuthHeader(request)
return nil
token.SetAuthHeader(request)
return nil
}, nil
}
3 changes: 0 additions & 3 deletions backend/pkg/iam/zitadel/bootstrap/zitadel.tf
Original file line number Diff line number Diff line change
Expand Up @@ -51,9 +51,6 @@ resource zitadel_login_policy openclarity_login_policy {
resource zitadel_project vmclarity_project {
name = "vmclarity"
org_id = zitadel_org.openclarity_org.id
project_role_assertion = true
project_role_check = true
has_project_check = true
private_labeling_setting = "PRIVATE_LABELING_SETTING_ENFORCE_PROJECT_RESOURCE_OWNER_POLICY"
}

Expand Down

0 comments on commit dfd8578

Please sign in to comment.