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 ¶
- Constants
- Variables
- func DefaultUnseal(ctx context.Context, sealed []byte) ([]byte, error)
- func DefaultUnsealEncoded(ctx context.Context, sealed []byte) ([]byte, error)
- func DefaultWaitForReady(ctx context.Context) error
- func Unseal(ctx context.Context, client *http.Client, endpoint string, sealed []byte) ([]byte, error)
- func UnsealEncoded(ctx context.Context, client *http.Client, endpoint string, sealed []byte) ([]byte, error)
- func WaitForReady(ctx context.Context, client *http.Client, endpoint string, ...) error
Examples ¶
Constants ¶
const DefaultWingmanURL = "http://localhost:8070"
The default URL base to use when accessing Wingman deployed as a sidecar on vk8s.
const StatusEndpoint = "/status"
Wingman REST status endpoint.
const UnsealEndpoint = "/secret/unseal"
The Wingman REST unseal endpoint.
Variables ¶
var ErrDeniedByPolicy = errors.New("denied by security policy")
ErrDeniedByPolicy is returned by unseal functions when access is denied by security policy used during seal.
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.
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 ¶
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 ¶
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 ¶
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.