iam

package
v1.40.2 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 14, 2023 License: Apache-2.0 Imports: 12 Imported by: 0

README

armory-cloud-iam

This is the Go version of lib-jvm-armory-cloud-iam

Core Package

The core package provides a principal service instance that retrieve JWKs from the Armory auth server and verifies the JWT on Armory-specific authorization headers. It accepts the following signing algorithms for JWT verification: RS256, RS384, RS512, PS256, PS384, PS512, ES256, ES384, ES512, ES256K, HS256, HS384, HS512, EdDSA

See the `examples directory to learn how to create the instance and verify the jwt. See Yeti for a real world example.

The principal service needs to be instantiated before verification. It is recommended that the JWT public keys url is set in the service's app config, since staging and prod auth servers are at different locations.

err := auth.CreatePrincipalServiceInstance(config.Auth.JWT.JWTKeysUrl); err != nil {
    log.Fatal("failed to initialize principal service")
}

This instance can be accessed later with:


psi := iam.GetPrincipalServiceInstance();

JWT Verification: Gorilla Mux Middleware

The ArmoryCloudPrincipalMiddleware accepts valid JWTs and rejects requests that do not pass JWT verfication on Armory-specific auth headers. It is up to the service that consumes this library to specify which paths and where in the mux handler chain this middleware will execute in.


http.Handle("/", psi.ArmoryCloudPrincipalMiddleware(r))

Pass in optional validators for verifying specific scopes or other properties on the principal required by your service. The validators will execute after the principal is fetched and verified.

// myCustomValidator checks if the user can access deployment information.
func myCustomValidator(p *ArmoryCloudPrincipal) error {
    if p.HasScope() {
        return nil
    }
    if p.OrgName == "myOrg" {
        return nil
    }
    return errors.New("not authorized")
}

The validators need to be passed in when creating the principal service instance.

err := iam.CreatePrincipalServiceInstance(config.Auth.JWT.JWTKeysUrl, myCustomValidator); err != nil {
    log.Fatal("failed to initialize principal service")
}

Validators is a variadic argument so multiple parameters can be passed in and will be validated in order.

err := auth.CreatePrincipalServiceInstance(config.Auth.JWT.JWTKeysUrl, myCustomValidator1, myCustomValidator2, myCustomValidator3); err != nil {
    log.Fatal("failed to initialize principal service")
}

Example middleware setup:

JWT Verification: Manual extraction

You can verify the token after extracting from the authorization headers manually if you do not wish to use the middleware and implement your own error handling:

token, err := a.ExtractAndVerifyPrincipalFromTokenString(tokenStr)

Documentation

Index

Constants

View Source
const (
	ArmoryCloudPrincipalClaimNamespace = "https://cloud.armory.io/principal"
)

Variables

View Source
var (
	ErrUnauthorized = errors.New("unauthorized")
)

Functions

func AuthMiddleware

func AuthMiddleware(ps *ArmoryCloudPrincipalService) func(handler http.Handler) http.Handler

AuthMiddleware Deprecated: this depreciated in favor of using the authn middleware bundled in the server package that returns a serr.Error

func DangerouslyWriteUnverifiedPrincipalToContext added in v1.15.0

func DangerouslyWriteUnverifiedPrincipalToContext(c context.Context, principal *ArmoryCloudPrincipal) context.Context

DangerouslyWriteUnverifiedPrincipalToContext is exposed for easily injecting stub principals into context for testing

func ExtractBearerToken added in v1.15.0

func ExtractBearerToken(r *http.Request) (string, error)

func GinAuthMiddleware

func GinAuthMiddleware(ps *ArmoryCloudPrincipalService, allowWithoutAuthList []string) gin.HandlerFunc

GinAuthMiddleware Deprecated: this depreciated in favor of using the authn middleware bundled in the server package that returns a serr.Error

func WithPrincipal

func WithPrincipal(ctx context.Context, principal ArmoryCloudPrincipal) context.Context

Types

type ArmoryCloudPrincipal

type ArmoryCloudPrincipal struct {

	//  PrincipalType The type of principal, user or machine
	Type PrincipalType `json:"type"`
	// Name  This is the principals name For user types this is will the users email address For machine  types this will be the identifier of the OIDC application that represents the machine
	Name string `json:"name"`
	// OrgId The guid for the organization the principal is a member of
	OrgId string `json:"orgId"`
	// OrgName The human-readable name of the organization
	OrgName string `json:"orgName"`
	// EnvId The guid for the environment (aka tenant) that this principal is authorized for
	EnvId string `json:"envId"`
	// ArmoryAdmin A flag to determine if the principal is an armory admin principal and can do dangerous x-org and or x-env actions.
	ArmoryAdmin bool `json:"armoryAdmin"`
	// Subject  The "sub" (subject) claim identifies the principal that is the subject of the JWT.  The "sub" value is a case-sensitive string containing a StringOrURI value.
	Subject string `json:"sub"`
	/// Issuer The "iss" (issuer) claim identifies the principal that issued the JWT.
	Issuer string `json:"iss"`
	// AuthorizedParty OPTIONAL. Authorized party - the party to which the ID Token was issued. If present, it MUST contain the OAuth 2.0 Client ID of this party. This Claim is only needed when the ID Token has
	// a single audience value and that audience is different from the authorized party. It MAY be included even when the authorized party is the same as the sole audience. The azp value is a case-sensitive string containing a StringOrURI value.
	AuthorizedParty string `json:"azp"`
	// Scopes A list of scopes that was set by the authorization server such as use:adminApi
	Scopes []string `json:"scopes"`
	// Roles List of groups that a principal belongs to
	Roles []string `json:"roles"`
}

func ExtractPrincipalFromContext

func ExtractPrincipalFromContext(ctx context.Context) (*ArmoryCloudPrincipal, error)

ExtractPrincipalFromContext can be used by any handler or downstream middleware of the ArmoryCloudPrincipalMiddleware to get the encoded principal for manual verification of scopes.

func (*ArmoryCloudPrincipal) HasScope

func (p *ArmoryCloudPrincipal) HasScope(scope string) bool

func (*ArmoryCloudPrincipal) String

func (p *ArmoryCloudPrincipal) String() string

func (*ArmoryCloudPrincipal) Tenant

func (p *ArmoryCloudPrincipal) Tenant() string

func (*ArmoryCloudPrincipal) ToJson

func (p *ArmoryCloudPrincipal) ToJson() string

func (*ArmoryCloudPrincipal) UnsafeHasScope added in v1.11.1

func (p *ArmoryCloudPrincipal) UnsafeHasScope(scope string) bool

type ArmoryCloudPrincipalService

type ArmoryCloudPrincipalService struct {
	JwtFetcher JwtFetcher
}

func New

New creates an ArmoryCloudPrincipalService. It downloads JWKS from the Armory Auth Server & populates the JWK Cache for principal verification.

func (*ArmoryCloudPrincipalService) ExtractAndVerifyPrincipalFromTokenBytes

func (a *ArmoryCloudPrincipalService) ExtractAndVerifyPrincipalFromTokenBytes(token []byte) (*ArmoryCloudPrincipal, error)

func (*ArmoryCloudPrincipalService) ExtractAndVerifyPrincipalFromTokenString

func (a *ArmoryCloudPrincipalService) ExtractAndVerifyPrincipalFromTokenString(token string) (*ArmoryCloudPrincipal, error)

func (*ArmoryCloudPrincipalService) VerifyPrincipalAndSetContext added in v1.15.0

func (a *ArmoryCloudPrincipalService) VerifyPrincipalAndSetContext(tokenOrRawHeader string, c *gin.Context) error

type Configuration added in v1.7.1

type Configuration struct {
	JWT            JWT      `yaml:"jwt"`
	RequiredScopes []string `yaml:"requiredScopes"`
}

type JWT

type JWT struct {
	JWTKeysURL string `yaml:"jwtKeysUrl"`
}

type JwtFetcher

type JwtFetcher interface {
	Download() error
	Fetch(token []byte) (interface{}, interface{}, error)
}

type JwtToken

type JwtToken struct {
	// contains filtered or unexported fields
}

func (*JwtToken) Download

func (j *JwtToken) Download() error

func (*JwtToken) Fetch

func (j *JwtToken) Fetch(token []byte) (interface{}, interface{}, error)

type PrincipalType

type PrincipalType string
const (
	User    PrincipalType = "user"
	Machine PrincipalType = "machine"
)

Directories

Path Synopsis

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL