Documentation ¶
Overview ¶
Package auth provides authentication for a client to a remote registry.
Index ¶
- Constants
- Variables
- func AppendScopes(ctx context.Context, scopes ...string) context.Context
- func CleanScopes(scopes []string) []string
- func GetScopes(ctx context.Context) []string
- func ScopeRepository(repository string, actions ...string) string
- func StaticCredential(registry string, cred Credential) func(context.Context, string) (Credential, error)
- func WithScopes(ctx context.Context, scopes ...string) context.Context
- type Cache
- type Client
- type Credential
- type Scheme
Examples ¶
Constants ¶
const ( // ActionPull represents generic read access for resources of the repository // type. ActionPull = "pull" // ActionPush represents generic write access for resources of the // repository type. ActionPush = "push" // ActionDelete represents the delete permission for resources of the // repository type. ActionDelete = "delete" )
Actions used in scopes. Reference: https://docs.docker.com/registry/spec/auth/scope/
const ScopeRegistryCatalog = "registry:catalog:*"
ScopeRegistryCatalog is the scope for registry catalog access.
Variables ¶
var DefaultClient = &Client{ Header: http.Header{ "User-Agent": {"oras-go"}, }, Cache: DefaultCache, }
DefaultClient is the default auth-decorated client.
Functions ¶
func AppendScopes ¶
AppendScopes appends additional scopes to the existing scopes in the context and returns a new context. The resulted scopes are de-duplicated. The append operation does modify the existing scope in the context passed in.
func CleanScopes ¶
CleanScopes merges and sort the actions in ascending order if the scopes have the same resource type and name. The final scopes are sorted in ascending order. In other words, the scopes passed in are de-duplicated and sorted. Therefore, the output of this function is deterministic. If there is a wildcard `*` in the action, other actions in the same resource type and name are ignored.
func ScopeRepository ¶
ScopeRepository returns a repository scope with given actions. Reference: https://docs.docker.com/registry/spec/auth/scope/
func StaticCredential ¶
func StaticCredential(registry string, cred Credential) func(context.Context, string) (Credential, error)
StaticCredential specifies static credentials for the given host.
func WithScopes ¶
WithScopes returns a context with scopes added. Scopes are de-duplicated. Scopes are used as hints for the auth client to fetch bearer tokens with larger scopes. For example, uploading blob to the repository "hello-world" does HEAD request first then POST and PUT. The HEAD request will return a challenge for scope `repository:hello-world:pull`, and the auth client will fetch a token for that challenge. Later, the POST request will return a challenge for scope `repository:hello-world:push`, and the auth client will fetch a token for that challenge again. By invoking `WithScopes()` with the scope `repository:hello-world:pull,push`, the auth client with cache is hinted to fetch a token via a single token fetch request for all the HEAD, POST, PUT requests. Passing an empty list of scopes will virtually remove the scope hints in the context. Reference: https://docs.docker.com/registry/spec/auth/scope/
Types ¶
type Cache ¶
type Cache interface { // GetScheme returns the auth-scheme part cached for the given registry. // A single registry is assumed to have a consistent scheme. // If a registry has different schemes per path, the auth client is still // workable. However, the cache may not be effective as the cache cannot // correctly guess the scheme. GetScheme(ctx context.Context, registry string) (Scheme, error) // GetToken returns the auth-token part cached for the given registry of a // given scheme. // The underlying implementation MAY cache the token for all schemes for the // given registry. GetToken(ctx context.Context, registry string, scheme Scheme, key string) (string, error) // Set fetches the token using the given fetch function and caches the token // for the given scheme with the given key for the given registry. // The return values of the fetch function is returned by this function. // The underlying implementation MAY combine the fetch operation if the Set // function is invoked multiple times at the same time. Set(ctx context.Context, registry string, scheme Scheme, key string, fetch func(context.Context) (string, error)) (string, error) }
Cache caches the auth-scheme and auth-token for the "Authorization" header in accessing the remote registry. Precisely, the header is `Authorization: auth-scheme auth-token`. The `auth-token` is a generic term as `token68` in RFC 7235 section 2.1.
type Client ¶
type Client struct { // Client is the underlying HTTP client used to access the remote // server. // If nil, http.DefaultClient is used. Client *http.Client // Header contains the custom headers to be added to each request. Header http.Header // Credential specifies the function for resolving the credential for the // given registry (i.e. host:port). // `EmptyCredential` is a valid return value and should not be considered as // an error. // If nil, the credential is always resolved to `EmptyCredential`. Credential func(context.Context, string) (Credential, error) // Cache caches credentials for direct accessing the remote registry. // If nil, no cache is used. Cache Cache // ClientID used in fetching OAuth2 token as a required field. // If empty, a default client ID is used. // Reference: https://docs.docker.com/registry/spec/auth/oauth/#getting-a-token ClientID string // ForceAttemptOAuth2 controls whether to follow OAuth2 with password grant // instead the distribution spec when authenticating using username and // password. // References: // - https://docs.docker.com/registry/spec/auth/jwt/ // - https://docs.docker.com/registry/spec/auth/oauth/ ForceAttemptOAuth2 bool }
Client is an auth-decorated HTTP client. Its zero value is a usable client that uses http.DefaultClient with no cache.
func (*Client) Do ¶
Do sends the request to the remote server, attempting to resolve authentication if 'Authorization' header is not set. On authentication failure due to bad credential, - Do returns error if it fails to fetch token for bearer auth. - Do returns the registry response without error for basic auth.
Example (BasicAuth) ¶
ExampleClient_Do_basicAuth gives an example of using client with credentials.
client := &auth.Client{ // expectedHostAddress is of form ipaddr:port Credential: auth.StaticCredential(expectedHostAddress, auth.Credential{ Username: username, Password: password, }), } // basicAuthTargetURL can be any URL. For example, https://registry.wabbit-networks.io/v2/ req, err := http.NewRequest(http.MethodGet, basicAuthTargetURL, nil) if err != nil { panic(err) } resp, err := client.Do(req) if err != nil { panic(err) } fmt.Println(resp.StatusCode)
Output: 200
Example (ClientConfigurations) ¶
ExampleClient_Do_clientConfigurations shows the client configurations available, including using cache, setting user agent and configuring OAuth2.
client := &auth.Client{ // expectedHostAddress is of form ipaddr:port Credential: auth.StaticCredential(expectedHostAddress, auth.Credential{ Username: username, Password: password, }), // ForceAttemptOAuth2 controls whether to follow OAuth2 with password grant. ForceAttemptOAuth2: true, // Cache caches credentials for accessing the remote registry. Cache: auth.NewCache(), } // SetUserAgent sets the user agent for all out-going requests. client.SetUserAgent("example user agent") // Tokens carry restrictions about what resources they can access and how. // Such restrictions are represented and enforced as Scopes. // Reference: https://docs.docker.com/registry/spec/auth/scope/ scopes := []string{ "repository:dst:pull,push", "repository:src:pull", } // WithScopes returns a context with scopes added. ctx := auth.WithScopes(context.Background(), scopes...) // clientConfigTargetURL can be any URL. For example, https://registry.wabbit-networks.io/v2/ req, err := http.NewRequestWithContext(ctx, http.MethodGet, clientConfigTargetURL, nil) if err != nil { panic(err) } resp, err := client.Do(req) if err != nil { panic(err) } fmt.Println(resp.StatusCode)
Output: 200
Example (MinimalClient) ¶
ExampleClient_Do_minimalClient gives an example of a minimal working client.
var client auth.Client // targetURL can be any URL. For example, https://registry.wabbit-networks.io/v2/ req, err := http.NewRequest(http.MethodGet, targetURL, nil) if err != nil { panic(err) } resp, err := client.Do(req) if err != nil { panic(err) } fmt.Println(resp.StatusCode)
Output: 200
Example (WithAccessToken) ¶
ExampleClient_Do_withAccessToken gives an example of using client with an access token.
client := &auth.Client{ // expectedHostAddress is of form ipaddr:port Credential: auth.StaticCredential(expectedHostAddress, auth.Credential{ AccessToken: accessToken, }), } // accessTokenTargetURL can be any URL. For example, https://registry.wabbit-networks.io/v2/ req, err := http.NewRequest(http.MethodGet, accessTokenTargetURL, nil) if err != nil { panic(err) } resp, err := client.Do(req) if err != nil { panic(err) } fmt.Println(resp.StatusCode)
Output: 200
Example (WithRefreshToken) ¶
ExampleClient_Do_withRefreshToken gives an example of using client with a refresh token.
client := &auth.Client{ // expectedHostAddress is of form ipaddr:port Credential: auth.StaticCredential(expectedHostAddress, auth.Credential{ RefreshToken: refreshToken, }), } // refreshTokenTargetURL can be any URL. For example, https://registry.wabbit-networks.io/v2/ req, err := http.NewRequest(http.MethodGet, refreshTokenTargetURL, nil) if err != nil { panic(err) } resp, err := client.Do(req) if err != nil { panic(err) } fmt.Println(resp.StatusCode)
Output: 200
func (*Client) SetUserAgent ¶
SetUserAgent sets the user agent for all out-going requests.
type Credential ¶
type Credential struct { // Username is the name of the user for the remote registry. Username string // Password is the secret associated with the username. Password string // RefreshToken is a bearer token to be sent to the authorization service // for fetching access tokens. // A refresh token is often referred as an identity token. // Reference: https://docs.docker.com/registry/spec/auth/oauth/ RefreshToken string // AccessToken is a bearer token to be sent to the registry. // An access token is often referred as a registry token. // Reference: https://docs.docker.com/registry/spec/auth/token/ AccessToken string }
Credential contains authentication credentials used to access remote registries.
var EmptyCredential Credential
EmptyCredential represents an empty credential.
type Scheme ¶
type Scheme byte
Scheme define the authentication method.
const ( // SchemeUnknown represents unknown or unsupported schemes SchemeUnknown Scheme = iota // SchemeBasic represents the "Basic" HTTP authentication scheme. // Reference: https://tools.ietf.org/html/rfc7617 SchemeBasic // SchemeBearer represents the Bearer token in OAuth 2.0. // Reference: https://tools.ietf.org/html/rfc6750 SchemeBearer )