Secret Source Extensions
Secret source extension allow users to write or use written by other users extensions in order to get secrets to be used within k6 tests.
Like JavaScript extensions, secret source extensions rely on the extension author to implement specific APIs.
Before you start:
To run this tutorial, you’ll need the following applications installed:
- Go
- Git
You also need to install xk6:
$ go install go.k6.io/xk6/cmd/xk6@latest
Write a simple extension
- Set up a directory to work in.
$ mkdir xk6-secret-source-cli; cd xk6-secret-source-cli; go mod init xk6-secret-source-cli
- The core of an Output extension is a struct that implements the
secrets.Source
interface.
Create a simple example secret source that just reads the secrets from the cli flag - similar to the in built mock
one.
- Register the module to use these from k6 test scripts.
package cli
import "go.k6.io/k6/secretsource"
// init is called by the Go runtime at application startup.
func init() {
secretsource.RegisterExtension("cli", newCLISecretSourceFromParams)
}
Note
You must use the registered with the
--secret-source
flag when running k6!
The final extension code looks like this:
Notice a couple of things:
The module initializer
newCLISecretSourceFromParams()
receives an instance ofsecretsource.Params
. With this object, the extension can access the secret source specific configuration, interfaces to the filesystem, it cli args, logger, etc.Get
in this example just returns from an internal array, but it also can do network requests or anything else it needs to get secrets.
Compile your extended k6
To build a k6 binary with this extension, run:
$ go mod tidy # this is needed by the go toolchain
$ xk6 build --with xk6-secret-source-cli=.
Note
xk6-secret-source-cli
is the Go module name passed togo mod init
Usually, this would be a URL similar to
github.com/grafana/xk6-secret-source-cli
.
Use your extension
Now we can use the extension with a test script.
- In new JavaScript file, make some simple test logic.
import secrets from 'k6/secrets';
export default async () => {
const my_secret = await secrets.get('cool'); // get secret from a source with the provided identifier
console.log(my_secret);
await secrets.get('else'); // get secret from a source with the provided identifier
console.log(my_secret); // print the same old secret to see that the secret from above will also be redacted
console.log('some'); // log the original secret but using its constant value
};
- Now, run the test.
./k6 run test.js --secret-source=cli=cool=some,else=console --quiet --no-summary
Note
The
--secret-source=cli=cool=some,else=console
argument tells k6 to use your custom secret source and gives its configuration. The flag--quiet --no-summary
configures k6 to show only custom output.
Your output should look something like this:
INFO[0000] ***SECRET_REDACTED*** source=console
INFO[0000] ***SECRET_REDACTED*** source="***SECRET_REDACTED***"
INFO[0000] ***SECRET_REDACTED*** source="***SECRET_REDACTED***"
As you can see there is quite a lot of redacted secrets. And also that console
is only redacted after it is accessed as before that k6 can not know it is actually a secret.
Note
Real world secrets are not expected to be common strings that will be found naturally in the k6 output as is in this example.
Things to keep in mind
Questions? Feel free to join the discussion on extensions in the k6 Community Forum.