auth

package
v0.0.0-...-11bd816 Latest Latest
Warning

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

Go to latest
Published: Apr 29, 2024 License: Apache-2.0 Imports: 20 Imported by: 0

Documentation

Index

Constants

This section is empty.

Variables

View Source
var AnonymousUserIdentity = keppel.UserIdentity(anonUserIdentity{})

AnonymousUserIdentity is a keppel.UserIdentity for anonymous users.

View Source
var CatalogEndpointScope = Scope{
	ResourceType: "registry",
	ResourceName: "catalog",
	Actions:      []string{"*"},
}

CatalogEndpointScope is the Scope for `GET /v2/_catalog`.

View Source
var InfoAPIScope = Scope{
	ResourceType: "keppel_api",
	ResourceName: "info",
	Actions:      []string{"access"},
}

InfoAPIScope is the Scope for all informational endpoints that are allowed for all non-anon users.

View Source
var PeerAPIScope = Scope{
	ResourceType: "keppel_api",
	ResourceName: "peer",
	Actions:      []string{"access"},
}

PeerAPIScope is the Scope for all endpoints below `/peer/`.

Functions

This section is empty.

Types

type Audience

type Audience struct {
	IsAnycast bool
	// When using a domain-remapped API, contains the account name specified in the domain name.
	// Otherwise, contains the empty string.
	AccountName string
}

Audience is an audience for which we can issue tokens.

NOTE: All members need to be public since audiences are JSON-serialized in test.Setup().getToken().

func IdentifyAudience

func IdentifyAudience(hostname string, cfg keppel.Configuration) Audience

IdentifyAudience returns the Audience corresponding to the given domain name. The hostname argument is either directly taken from a request URL (for regular API requests), from the "service" value of auth requests, or from the "audience" field in tokens.

func (Audience) Hostname

func (a Audience) Hostname(cfg keppel.Configuration) string

Hostname returns the hostname that is used as the "audience" value in tokens and as the "service" value in auth challenges. This is the inverse operation of IdentifyAudience in the following sense:

audience == IdentifyAudience(audience.Hostname(cfg), cfg)

func (Audience) IssuerKeys

func (a Audience) IssuerKeys(cfg keppel.Configuration) []crypto.PrivateKey

IssuerKeys returns the issuer keys that are used to sign tokens for this service. Index [0] contains the key that shall be used for new tokens, but all keys are acceptable in existing tokens (to support seamless key rotation).

func (Audience) MapPeerHostname

func (a Audience) MapPeerHostname(peerHostname string) string

PeerHostname takes the KEPPEL_API_PUBLIC_FQDN of a peer, and adds domain-remapping to it if necessary. This is used when reverse-proxying anycast requests to a peer, to ensure that domain-remapped requests stay domain-remapped.

type Authorization

type Authorization struct {
	// UserIdentity identifies the user that sent the request.
	UserIdentity keppel.UserIdentity
	// ScopeSet identifies the permissions granted to the user for the duration of
	// this request.
	ScopeSet ScopeSet
	// Audience identifies the API endpoint where the user sent the request.
	Audience Audience
}

Authorization describes the access rights of a particular user session, i.e. in the scope of an individual API request.

func (Authorization) IssueToken

func (a Authorization) IssueToken(cfg keppel.Configuration) (*TokenResponse, error)

IssueToken renders the given Authorization into a JWT token that can be used as a Bearer token to authenticate on Keppel's various APIs.

func (Authorization) IssueTokenWithExpires

func (a Authorization) IssueTokenWithExpires(cfg keppel.Configuration, expiresIn time.Duration) (*TokenResponse, error)

IssueTokenWithExpires renders the given Authorization into a JWT token that can be used as a Bearer token to authenticate on Keppel's various APIs with configurable expiring time

type IncomingRequest

type IncomingRequest struct {
	// The incoming request.
	HTTPRequest *http.Request
	// The required token scopes for this request. If the Authorization.ScopeSet
	// ends up not containing these scopes, the request is rejected and an auth
	// challenge is issued.
	Scopes ScopeSet
	// Whether anycast requests are acceptable on this endpoint.
	AllowsAnycast bool
	// Whether domain-remapped requests are acceptable on this endpoint.
	AllowsDomainRemapping bool
	// Filled when the user is trying to get a token from us. This enables basic
	// auth with username+password, and overrides the usual audience-sensing logic.
	AudienceForTokenIssuance *Audience
	// If this field is true, 403 is returned to indicate insufficient
	// authorization. Most APIs return 401 instead to ensure bug-for-bug
	// compatibility with Docker Registry.
	CorrectlyReturn403 bool
	// If true, Authorize() will not check if all requested scopes where
	// authorized.
	PartialAccessAllowed bool
	// If true, Authorize() will not assume an AnonymousUserIdentity when no auth
	// headers are provided. Users MUST present some sort of auth header.
	NoImplicitAnonymous bool
}

IncomingRequest describes everything we need to know about an incoming API request in order to check for Authorization.

func (IncomingRequest) Authorize

Authorize checks if the given incoming request has a proper Authorization. If an error is returned, the given `errHeaders` must be added to the HTTP response.

type ParsedRepositoryScope

type ParsedRepositoryScope struct {
	AccountName        string
	RepositoryName     string
	FullRepositoryName string
}

ParsedRepositoryScope is returned by Scope.ParseRepositoryScope().

type PeerUserIdentity

type PeerUserIdentity struct {
	PeerHostName string
}

PeerUserIdentity is a keppel.UserIdentity for peer users with global read access and access to the specialized peer API.

This type used to be called ReplicationUserIdentity, which is why usernames start with `replication@` and why serialization uses the type name "repl".

func (*PeerUserIdentity) DeserializeFromJSON

func (uid *PeerUserIdentity) DeserializeFromJSON(in []byte, _ keppel.AuthDriver) error

DeserializeFromJSON implements the keppel.UserIdentity interface.

func (*PeerUserIdentity) HasPermission

func (uid *PeerUserIdentity) HasPermission(perm keppel.Permission, tenantID string) bool

HasPermission implements the keppel.UserIdentity interface.

func (*PeerUserIdentity) PluginTypeID

func (uid *PeerUserIdentity) PluginTypeID() string

UserType implements the keppel.UserIdentity interface.

func (*PeerUserIdentity) SerializeToJSON

func (uid *PeerUserIdentity) SerializeToJSON() (payload []byte, err error)

SerializeToJSON implements the keppel.UserIdentity interface.

func (*PeerUserIdentity) UserInfo

func (uid *PeerUserIdentity) UserInfo() audittools.UserInfo

UserInfo implements the keppel.UserIdentity interface.

func (*PeerUserIdentity) UserName

func (uid *PeerUserIdentity) UserName() string

UserName implements the keppel.UserIdentity interface.

func (*PeerUserIdentity) UserType

func (uid *PeerUserIdentity) UserType() keppel.UserType

UserType implements the keppel.UserIdentity interface.

type Scope

type Scope struct {
	ResourceType string   `json:"type"`
	ResourceName string   `json:"name"`
	Actions      []string `json:"actions"`
}

Scope contains the fields of the "scope" query parameter in a token request.

func (Scope) Contains

func (s Scope) Contains(other Scope) bool

Contains returns true if this scope is for the same resource as the other scope, and if it contains all the actions that the other contains.

func (Scope) ParseRepositoryScope

func (s Scope) ParseRepositoryScope(audience Audience) ParsedRepositoryScope

ParseRepositoryScope interprets the resource name of a scope with resource type "repository".

This is more complicated than it would appear in first sight since the audience plays a role in how repository scopes look: On the regular APIs, the scope "repository:foo/bar:pull" refers to the repository "bar" in the account "foo". On the domain-remapped API for that account, the same repository would be accessed with the scope "repository:bar:pull".

I'm well aware that everything would be much easier if we used "repository:foo/bar:pull" all the time, but our hand is being forced by the Docker client here. It auto-guesses repository scopes based on the repository URL, which for domain-remapped APIs only has the repository name in the URL path.

func (Scope) String

func (s Scope) String() string

String serializes this scope into the format used in the Docker auth API.

type ScopeSet

type ScopeSet []*Scope

ScopeSet is a set of scopes.

func NewScopeSet

func NewScopeSet(scopes ...Scope) (ss ScopeSet)

NewScopeSet initializes a ScopeSet.

func (ScopeSet) AccountsWithCatalogAccess

func (ss ScopeSet) AccountsWithCatalogAccess(markerAccountName string) []string

AccountsWithCatalogAccess returns the names of all accounts whose contents can be listed with the access level in this ScopeSet. If `markerAccountName` is not empty, only accounts with `name > markerAccountName` will be returned.

For use with the /v2/_catalog endpoint.

func (*ScopeSet) Add

func (ss *ScopeSet) Add(s Scope)

Add adds a scope to this ScopeSet. If the ScopeSet already contains a Scope referring to the same resource, it is merged with the given scope.

func (ScopeSet) Contains

func (ss ScopeSet) Contains(s Scope) bool

Contains returns true if the given token authorizes the user for this scope.

func (ScopeSet) Flatten

func (ss ScopeSet) Flatten() []Scope

Flatten returns the scope set as a plain list of scopes.

type TokenResponse

type TokenResponse struct {
	Token     string `json:"token"`
	ExpiresIn uint64 `json:"expires_in"`
	IssuedAt  string `json:"issued_at"`
}

TokenResponse is the format expected by Docker in an auth response. The Token field contains a Java Web Token (JWT).

func IssueTokenForTrivy

func IssueTokenForTrivy(cfg keppel.Configuration, repoFullName string) (*TokenResponse, error)

IssueTokenForTrivy issues a token for Trivy to pull the image and it's databases with. This needs to use the specialized TrivyUserIdentity to avoid updating the image's "last_pulled_at" timestamp.

type TrivyUserIdentity

type TrivyUserIdentity struct{}

TrivyUserIdentity is a keppel.UserIdentity for peer users with global read access and access to the specialized peer API.

func (*TrivyUserIdentity) DeserializeFromJSON

func (uid *TrivyUserIdentity) DeserializeFromJSON(in []byte, _ keppel.AuthDriver) error

DeserializeFromJSON implements the keppel.UserIdentity interface.

func (*TrivyUserIdentity) HasPermission

func (uid *TrivyUserIdentity) HasPermission(perm keppel.Permission, tenantID string) bool

HasPermission implements the keppel.UserIdentity interface.

func (*TrivyUserIdentity) PluginTypeID

func (uid *TrivyUserIdentity) PluginTypeID() string

UserType implements the keppel.UserIdentity interface.

func (*TrivyUserIdentity) SerializeToJSON

func (uid *TrivyUserIdentity) SerializeToJSON() (payload []byte, err error)

SerializeToJSON implements the keppel.UserIdentity interface.

func (*TrivyUserIdentity) UserInfo

func (uid *TrivyUserIdentity) UserInfo() audittools.UserInfo

UserInfo implements the keppel.UserIdentity interface.

func (*TrivyUserIdentity) UserName

func (uid *TrivyUserIdentity) UserName() string

UserName implements the keppel.UserIdentity interface.

func (*TrivyUserIdentity) UserType

func (uid *TrivyUserIdentity) UserType() keppel.UserType

UserType implements the keppel.UserIdentity interface.

Jump to

Keyboard shortcuts

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