wingman

package
v1.2.1 Latest Latest
Warning

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

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

Documentation

Overview

Package wingman provides high-level functions that can interact with an F5XC wingman container.

The package provides DefaultUnseal and DefaultUnsealEncoded that receive a byte array containing . E.g. if you used vesctl to blindfold a file and

Index

Examples

Constants

View Source
const DefaultWingmanURL = "http://localhost:8070"

The default URL base to use when accessing Wingman deployed as a sidecar on vk8s.

View Source
const StatusEndpoint = "/status"

Wingman REST status endpoint.

View Source
const UnsealEndpoint = "/secret/unseal"

The Wingman REST unseal endpoint.

Variables

View Source
var ErrDeniedByPolicy = errors.New("denied by security policy")

ErrDeniedByPolicy is returned by unseal functions when access is denied by security policy used during seal.

View Source
var ErrNotReady = errors.New("wingman is not ready")

ErrNotReady indicates that Wingman service has not reported as ready to receive requests before the context was canceled.

View Source
var ErrUnexpectedHTTPStatus = errors.New("wingman returned an unexpected status code")

ErrUnexpectedHTTPStatus is returned by unseal functions when wingman response status is not 200, 403 or 503.

Functions

func DefaultUnseal

func DefaultUnseal(ctx context.Context, sealed []byte) ([]byte, error)

Unseal a byte slice of blindfold data, and returns a byte array of the unsealed data, using a sidecar Wingman listening on HTTP port 8070.

The sealed bytes will be base64 encoded before sending request; if you have a base64 encoded blindfold secret, as output from vesctl say, use DefaultUnsealEncoded function to avoid double-encoding of the sealed data.

Example
package main

import (
	"context"
	"fmt"
	"time"

	"github.com/memes/f5xc/wingman"
)

func main() {
	// Allow wingman up to 10 seconds to try to unseal a secret
	ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
	defer cancel()
	secretData, err := wingman.DefaultUnseal(ctx, []byte("Guvf vf n grfg")) // spell-checker: disable-line
	if err != nil {
		fmt.Printf("Failure unsealing blindfold secret: %v", err)
		return
	}
	// Use the unsealed secret data
	fmt.Printf("secretData is %v", secretData)
}
Output:

Failure unsealing blindfold secret: failure during unseal request: Post "http://localhost:8070/secret/unseal": dial tcp 127.0.0.1:8070: connect: connection refused
Example (File)
package main

import (
	"context"
	"fmt"
	"os"
	"time"

	"github.com/memes/f5xc/wingman"
)

func main() {
	// Read the sealed file into a byte array
	sealed, err := os.ReadFile("testdata/blindfold.raw")
	if err != nil {
		fmt.Printf("failed to open blindfold file: %v", err)
		return
	}

	// Allow wingman up to 10 seconds to try to unseal a secret
	ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
	defer cancel()
	secretData, err := wingman.DefaultUnseal(ctx, sealed)
	if err != nil {
		fmt.Printf("Failure unsealing blindfold secret: %v", err)
		return
	}
	// Use the unsealed secret data
	fmt.Printf("secretData is %v", secretData)
}
Output:

Failure unsealing blindfold secret: failure during unseal request: Post "http://localhost:8070/secret/unseal": dial tcp 127.0.0.1:8070: connect: connection refused

func DefaultUnsealEncoded

func DefaultUnsealEncoded(ctx context.Context, sealed []byte) ([]byte, error)

Unseal a byte slice of base64 encoded blindfold data, and returns a byte array of the unsealed data, using a sidecar Wingman listening on HTTP port 8070.

The sealed bytes will be embedded in the request as-is; use DefaultUnseal if the sealed bytes must be base64 encoded as required by Wingman's unseal endpoint.

Example
package main

import (
	"context"
	"fmt"
	"time"

	"github.com/memes/f5xc/wingman"
)

func main() {
	// Allow wingman up to 10 seconds to try to unseal a secret
	ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
	defer cancel()
	secretData, err := wingman.DefaultUnsealEncoded(ctx, []byte("R3V2ZiB2ZiBuIGdyZmc="))
	if err != nil {
		fmt.Printf("Failure unsealing blindfold secret: %v", err)
		return
	}
	// Use the unsealed secret data
	fmt.Printf("secretData is %v", secretData)
}
Output:

Failure unsealing blindfold secret: failure during unseal request: Post "http://localhost:8070/secret/unseal": dial tcp 127.0.0.1:8070: connect: connection refused
Example (File)
package main

import (
	"context"
	"fmt"
	"os"
	"time"

	"github.com/memes/f5xc/wingman"
)

func main() {
	// Read the sealed file into a byte array
	sealed, err := os.ReadFile("testdata/blindfold.b64")
	if err != nil {
		fmt.Printf("failed to open blindfold file: %v", err)
		return
	}

	// Allow wingman up to 10 seconds to try to unseal a secret
	ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
	defer cancel()
	secretData, err := wingman.DefaultUnsealEncoded(ctx, sealed)
	if err != nil {
		fmt.Printf("Failure unsealing blindfold secret: %v", err)
		return
	}
	// Use the unsealed secret data
	fmt.Printf("secretData is %v", secretData)
}
Output:

Failure unsealing blindfold secret: failure during unseal request: Post "http://localhost:8070/secret/unseal": dial tcp 127.0.0.1:8070: connect: connection refused

func DefaultWaitForReady

func DefaultWaitForReady(ctx context.Context) error

DefaultWaitForReady will poll the default Wingman sidecar status endpoint every 10 seconds and will return nil once the response has a 200 status code and a body that is READY.

All transient connection errors, HTTP errors, and other status codes are silently ignored and polling will continue. An error will only be returned if a valid http.Request cannot be created from the endpoint, or if the context is canceled or completed before a successful response is received the error will be ErrNotReady.

Example
package main

import (
	"context"
	"fmt"
	"time"

	"github.com/memes/f5xc/wingman"
)

func main() {
	// Wait up to 10 seconds for Wingman to be ready - for production-ready implementations this should be much
	// higher to give wingman enough time to initialize and be ready to unseal secrets.
	ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
	defer cancel()
	if err := wingman.DefaultWaitForReady(ctx); err != nil {
		fmt.Printf("Failure waiting for Wingman to be ready: %v", err)
	}
}
Output:

Failure waiting for Wingman to be ready: wingman is not ready

func Unseal

func Unseal(ctx context.Context, client *http.Client, endpoint string, sealed []byte) ([]byte, error)

Unseal a byte slice of blindfold data, and returns a byte array of the unsealed data.

The sealed bytes will be base64 encoded before sending request; if you have a base64 encoded blindfold secret, as generated directly from vesctl say, use UnsealEncoded function to avoid double-encoding of the sealed data.

It is the callers responsibility to ensure that the http.Client and endpoint are suitable for communicating with Wingman; the function DefaultUnseal can be used if Wingman is deployed as a sidecar listening on default port.

func UnsealEncoded

func UnsealEncoded(ctx context.Context, client *http.Client, endpoint string, sealed []byte) ([]byte, error)

Unseal a byte slice of base64 encoded blindfold data, and returns a byte array of the unsealed data.

The sealed bytes will be embedded in the request as-is; use Unseal if the sealed bytes must be base64 encoded as required by Wingman's unseal endpoint.

It is the callers responsibility to ensure that the http.Client and endpoint are suitable for communicating with Wingman; the function DefaultUnsealEncoded can be used if Wingman is deployed as a sidecar listening on default port.

func WaitForReady

func WaitForReady(ctx context.Context, client *http.Client, endpoint string, sleepBetweenAttempts time.Duration) error

WaitForReady will poll the Wingman status endpoint and return nil when the response has a 200 status code and a body that is READY.

All transient connection errors, HTTP errors, and other status codes are silently ignored and polling will continue. An error will only be returned if a valid http.Request cannot be created from the endpoint, or if the context is canceled or completed before a successful response is received the error will be ErrNotReady.

It is the callers responsibility to ensure that the http.Client and endpoint are suitable for communicating with Wingman; the function DefaultWaitForReady can be used if Wingman is deployed as a sidecar listening on default port.

Types

This section is empty.

Jump to

Keyboard shortcuts

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