Skip to content
Open
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
49 changes: 49 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -193,6 +193,55 @@ if err != nil {
fmt.Println(secrets[0].Value)
```

## How to fetch a Docker Hub access token

The client exposes a Docker Hub authentication accessor via `HubAuth()`. It
locates the right credential and decodes the JSON payload into a typed
`UserSession`, so you don't need to know the realm layout or the payload
format:

```go
import (
"github.com/docker/secrets-engine/client"
"github.com/docker/secrets-engine/client/dockerhub"
)

c, err := client.New()
if err != nil {
log.Fatalf("failed to create secrets engine client: %v", err)
}
hub := c.HubAuth()

// Fetch the session of the default signed-in account ...
session, err := hub.GetDefaultSession(context.Background())
if errors.Is(err, dockerhub.ErrNoSession) {
// Also matches dockerhub.ErrNoDefaultProfile, which wraps ErrNoSession.
log.Fatalf("not signed in to Docker Hub")
}
if err != nil {
log.Fatalf("failed fetching access token: %v", err)
}

// ... or fetch the session of a specific account.
session, err = hub.GetSession(context.Background(), "myuser")
if err != nil {
log.Fatalf("failed fetching access token: %v", err)
}

fmt.Println(session.AccessToken) // the raw JWT access token
fmt.Println(session.Claims.Username) // decoded token claims
fmt.Println(session.Claims.ExpiresAt)

// List the profiles of all signed-in accounts.
profiles, err := hub.ListProfiles(context.Background())
if err != nil {
log.Fatalf("failed listing profiles: %v", err)
}
for _, profile := range profiles {
fmt.Println(profile.Username, profile.UserID)
}
```

## How to create a plugin

### 1. Implement the plugin interface
Expand Down
8 changes: 8 additions & 0 deletions client/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import (

"connectrpc.com/connect"

"github.com/docker/secrets-engine/client/dockerhub"
"github.com/docker/secrets-engine/x/api"
healthv1 "github.com/docker/secrets-engine/x/api/health/v1"
"github.com/docker/secrets-engine/x/api/health/v1/healthv1connect"
Expand Down Expand Up @@ -152,6 +153,10 @@ func (c client) GetSecrets(ctx context.Context, pattern secrets.Pattern) ([]secr
return envelopes, nil
}

func (c client) HubAuth(opts ...dockerhub.Option) dockerhub.ClientAuth {
return dockerhub.New(c, opts...)
}

func (c client) Version(ctx context.Context) (DaemonVersion, error) {
resp, err := c.versionClient.GetVersion(ctx, connect.NewRequest(healthv1.GetVersionRequest_builder{}.Build()))
if isDialError(err) {
Expand All @@ -174,6 +179,9 @@ type Client interface {

// Version returns the name and version reported by the daemon.
Version(ctx context.Context) (DaemonVersion, error)

// HubAuth returns a Docker Hub authentication accessor backed by this client.
HubAuth(opts ...dockerhub.Option) dockerhub.ClientAuth
}

type PluginManagement interface {
Expand Down
8 changes: 8 additions & 0 deletions client/client_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ import (
"google.golang.org/protobuf/proto"
"google.golang.org/protobuf/types/known/timestamppb"

"github.com/docker/secrets-engine/client/dockerhub"
"github.com/docker/secrets-engine/x/api"
healthv1 "github.com/docker/secrets-engine/x/api/health/v1"
"github.com/docker/secrets-engine/x/api/health/v1/healthv1connect"
Expand Down Expand Up @@ -319,6 +320,13 @@ func TestSecretsEngineUnavailable(t *testing.T) {
require.ErrorIs(t, err, ErrSecretsEngineNotAvailable)
}

func TestHubAuth(t *testing.T) {
client, err := New(WithSocketPath(testhelper.RandomShortSocketName()))
require.NoError(t, err)
assert.NotNil(t, client.HubAuth())
assert.NotNil(t, client.HubAuth(dockerhub.Staging()))
}

func TestIsDialError(t *testing.T) {
require.True(t, isDialError(&net.OpError{
Op: "dial",
Expand Down
Loading
Loading