-
Notifications
You must be signed in to change notification settings - Fork 141
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
This adds the Locust file used to run a load test against Fulcio. Signed-off-by: Hayden Blauzvern <hblauzvern@google.com>
- Loading branch information
1 parent
0df4239
commit 5cdd33f
Showing
3 changed files
with
94 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
# Fulcio Performance Test | ||
|
||
## Overview | ||
|
||
[Learn more about Locust](http://docs.locust.io/en/stable/index.html). | ||
|
||
1. Install Locust with `pip3 install -r requirements.txt` | ||
1. Fetch an identity token for a service account with `gcloud auth print-identity-token --audiences sigstore --impersonate-service-account <name>@<project-id>.iam.gserviceaccount.com --include-email`. | ||
1. Start `locust`, configuring number of users, spawn rate, host, maximum QPS per user, and identity token. | ||
|
||
## Running Locust | ||
|
||
### Installation | ||
|
||
Run `pip3 install -r requirements.txt`, which will install Locust and necessary libraries. | ||
|
||
Confirm a successful install with `locust -V`, which should print the version. You may need to include `~/.local/bin` in your PATH. | ||
|
||
### Fetching identity token | ||
|
||
To fetch a certificate, you will need an OIDC token from one of the [OIDC issuers](https://github.com/sigstore/fulcio/blob/main/config/fulcio-config.yaml). One way is to fetch a token from Google. Note that you will need to install [`gcloud`](https://cloud.google.com/sdk/gcloud) and create a service account. A service account is necessary for the `--include-email` flag, which is needed to get an OIDC token with the correct format for Fulcio. | ||
|
||
Run the following command, and record the output: | ||
|
||
`gcloud auth print-identity-token --audiences sigstore --impersonate-service-account <name>@<project-id>.iam.gserviceaccount.com --include-email` | ||
|
||
Note that this token will be valid for approximately one hour. | ||
|
||
### Configuring maximum QPS per user | ||
|
||
You can configure the test to set a maximum QPS per user. This will limit each Locust user to the specified QPS. Without this, Locust will generate an unbounded amount of traffic. You can choose to remove `wait_time` if you want this behavior, but be careful to not overwhelm a production instance. | ||
|
||
### Running test | ||
|
||
From within the directory with `locustfile.py`, run the command `locust`. Open `localhost:8089` in a browser. Note you can also run `locust` from the command line, see the [documentation](http://docs.locust.io/en/stable/configuration.html#configuration). | ||
|
||
From the browser, set the following: | ||
* Number of users. Each will run at a maximum QPS based on maximum QPS set below. | ||
* Spawn rate, how often users are created per second | ||
* Host, either `localhost:port` if you're running a local instance of Fulcio or `https://v1.fulcio.sigstore.dev` | ||
* Token - The identity token from `gcloud auth` | ||
* Max QPS per user | ||
|
||
Click 'Start Swarming', and monitor for errors. | ||
|
||
## Results (12/14/21) | ||
|
||
https://github.com/sigstore/fulcio/issues/193#issuecomment-994247492 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
import base64 | ||
|
||
from cryptography.hazmat.primitives import hashes | ||
from cryptography.hazmat.primitives.asymmetric import ec | ||
from cryptography.hazmat.primitives.serialization import Encoding, PublicFormat | ||
from locust import HttpUser, task, constant_throughput, events | ||
import jwt | ||
|
||
@events.init_command_line_parser.add_listener | ||
def _(parser): | ||
parser.add_argument("--token", type=str, env_var="LOCUST_OIDC_TOKEN", default="", help="OIDC token for authentication with Fulcio") | ||
parser.add_argument("--max-qps-per-user", type=float, env_var="LOCUST_MAX_QPS_PER_USER", default=1.0, help="Maximum QPS per user") | ||
|
||
class FulcioUser(HttpUser): | ||
# FulcioUser represents an instance of a user making requests. | ||
|
||
# Maximum number of requests per second per user. For example, to reach 25 QPS, | ||
# run Locust with 25 users with a constant throughput of 1. | ||
def wait_time(self): | ||
return constant_throughput(self.environment.parsed_options.max_qps_per_user)(self) | ||
|
||
@task | ||
def create_cert(self): | ||
# create_cert generates a keypair and makes a request to Fulcio to fetch a certificate. | ||
|
||
# Static ID token. This avoids hitting the OIDC provider with each request to fetch a new token. | ||
token = self.environment.parsed_options.token | ||
|
||
# Generate keypair for challenge. | ||
privkey = ec.generate_private_key(ec.SECP256R1) | ||
pubkey = privkey.public_key() | ||
pubbytes = pubkey.public_bytes(Encoding.DER, PublicFormat.SubjectPublicKeyInfo) | ||
content = base64.b64encode(pubbytes).decode("utf-8") | ||
|
||
# Fetch identity of token and sign. | ||
email = jwt.decode(token, options={"verify_signature":False})['email'] | ||
data = email.encode() | ||
signature = privkey.sign(data, ec.ECDSA(hashes.SHA256())) | ||
challenge = base64.b64encode(signature).decode("utf-8") | ||
|
||
json = {"publicKey": {"content": content,"algorithm":"ecdsa"},"signedEmailAddress":challenge} | ||
response = self.client.post("/api/v1/signingCert", json=json, headers={"Authorization": f"Bearer {token}", "Content-Type":"application/json"}) | ||
print("Response status code:", response.status_code) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
cryptography | ||
locust | ||
pyjwt |