Skip to content

feat(dpop): add option to generate DPoP JWTs

Félix Veillette-Potvin requested to merge fvpotvin-dpop-addon into main

Description

This adds a feature to generate DPoP (demonstrating-proof-of-possession) proof JWTs. It's related to this blueprint and work we're doing to provide users a more restricted and secure way of controlling PAT usage. This is the first ever MR in support of this feature and there's no backend support yet. It's the first iteration!

Related Issues

Sender constraining personal access tokens (gitlab#425130)

Integration of the generation of a JWT to allow... (#7431)

https://gitlab.com/gitlab-com/gl-security/appsec/security-feature-blueprints/-/merge_requests/1+

How has this been tested?

Unit tests and using ssh-keygen to generate every type of supported SSH key.

Example:

$ ssh-keygen -t rsa -b 4096 -C "your_email@example.com"
Generating public/private rsa key pair.
Enter file in which to save the key (/home/dcouture/.ssh/id_rsa): testkey
Enter passphrase (empty for no passphrase): 
Enter same passphrase again: 
Your identification has been saved in testkey
Your public key has been saved in testkey.pub
The key fingerprint is:
SHA256:E2oBw1HGhTaxKMrKiPex09QfqEGgnxtCL6zcnZ09SzQ your_email@example.com
The key's randomart image is:
+---[RSA 4096]----+
|   .++++.        |
|    o==.         |
|  ...oo..        |
|..o.  .o .       |
|.+ o oo.SE       |
|= + =.o +.o      |
|=oooo=oooo .     |
|.o oo=oo.o.      |
|    o.   .o      |
+----[SHA256]-----+
$ ./bin/glab auth dpop-generate --private-key testkey
2024/01/11 15:24:25 DPoP Proof: eyJhbGciOiJSUzUxMiIsImp3ayI6eyJlIjoiQVFBQiIsIm4iOiIzendIeEI1VTFZYS10ZDA0Sm05OGJtZ2tNS0RscjZXeWpBcDE3eDczaHRjOHJBMkpzTF9aZDcxY00ybk4xZjVaclUwN1FHVGNNZnFWQkpjRU5vbWNXRFNEMERKMU9CNWtrM2FuNmtGS3JBcVZkQWNnX0RUUnZ0ZGpKNkozaGRldG5OYWI5LVVPcjBPc1VLeGh2UFY2aHRZeGl4VFMtV1U4LUR0Z1pVZ2hfM1dZMjQyLTY1UjMySVFKQ0pQOWlHQWNjcFBfSy1JYmZ5emYydTVjQkZpMTNTM29aN1h0YmhvU0pmNHRqVG05a3RYS0cxRVFBTHY4SDZmSXZUSnJPY293TFZ1ZkFUYWF3djlkekxvWDF0V1NwOGdwMTFCV2pnYXFaRERVclFCdlZ6MHZsMV9RRnpjdXRqcjVkdmVKb2lKRnJfd2lRR2J2MnRsT3pIRTFnWmptWHRpR09iT1JiS3RFZ2xMc2hQODlOcGJxUTUtZ3Zzc0loU3d3amZCMEY4T19DMWVSSW9yV0ZnbjNGNTVsZzNiU2k1WTZLMUE1NHdxdEZwRzFPcFBXak1tVGxqeUoxN0JsMjlJbTltTWh4cXhTTEoyV0VWaU9HdmRGSG51M1VTd25kOUNuMm1ZWUh6dzZGdURreWFlUjdVcmpjRGYxQnBXR0Z5WFJzM3JUd0xha2hrRXdqM1h6Q3h3ZHQ1WVJhdmstU1hNTy1rOUl0d0dSRVJWNDFna21MUWdqTURtNTdUdDNucXNPdkZtei1ydkJvdDQ3MFMtcUdEbzF6V0Zza3BTMVcyUDlhWEU2bmlmS3daNEkyQU00eDVPdGkySkMzanptNHZXcF9YZFJnd0VVYndBdTI4TlQ0amFibUxJcERRVkJzQ3RHSXRQS2R0Y3VtaVRiOXlOTzZLOCIsImt0eSI6IlJTQSJ9LCJ0eXAiOiJkcG9wK2p3dCJ9.eyJleHAiOjE3MDQ5ODMzNjUsImlhdCI6MTcwNDk4MzA2NSwianRpIjoiN2FkMmFiOTctOGYyZi00MTkxLTgyNGYtMjFiODk2M2MyYTJjIiwiaHRtIjoiIiwiaHR1IjoiIiwiYXRoIjoiSFIzaG94Q21EcFo2RUpETTJzLTRPa29IUmU2V1pPZG1qenhSZzFjVUwzbyJ9.f1xtfuTdTe4b-fS_dz0GaqThT_e1dQIyldDacdyEzF-UJ4vJblXdGM1mV3h3A_kS9AsJQaBI4A_tNVphOCjx22f7_4YjVIaLprYxoAXV0iJx6FgAVO478uvyW9y_5idUjUBFo4h2KGPiDlvNo6w4wm6gFAvSHVS37RgPUikOxMJnnPeMO_2e3boQXmYjjSUq6aODmE-x6yub_hWNsF4s0aAP1ydqFIGclokGPZ-WpL_W38KjNXGeG7kRkhpLw4f4xF169TNcr7VGiuRjmsLPaoo5Klu4jRHKV8LXZbTZF-ScC8QwEb_xXTpZMKKqu_wvKLtyTz32l6mMQO4R3Uuilytv_-Lx5Bp2HEMynjqxT6y7YlY4FNL7amJItWJeesDcX3QkZWOMAcLK0BcB2pBox1KsQGhqcWC71ZnIW7HCWsr0TGdyIc7sBj1YWvTEAG_lmynhktS6BTRcKMKRvb4fTfKY635e-KG-0IV4_jbHBEYSZHgn1Ed4bdomQxSC8ArbGCgWLIdXf9NAepkOHTqA9PXuyzlNZ8jYTC1MfCZGWogV8oKqlc25H7admukhO5nsXMEsFmle1Zhqy0xViAtSGQ2mo2QoC3GAJcJsTNg6pJFNP4xDe6fpXyVIaeY4YXFCYj0R1KoOdiwzxbSrlNoJ9PqFiyT23CGkKwJwsTSEleE

I'm using Ubuntu to test this.

Screenshots (if appropriate):

Not a screenshot but here's the help output

$ ./bin/glab auth --help
Manage glab's authentication state

USAGE
  glab auth <command> [flags]

CORE COMMANDS
  dpop-generate: Generates a DPoP (demonstrating-proof-of-possession) proof JWT
  login:         Authenticate with a GitLab instance
  status:        View authentication status

INHERITED FLAGS
  --help   Show help for command

LEARN MORE
  Use 'glab <command> <subcommand> --help' for more information about a command.
$ ./bin/glab auth dpop-generate --help 
[Experiment] Demonstrating-proof-of-possession (DPoP, <https://gitlab.com/gitlab-com/gl-security/appsec/security-feature-blueprints/-/blob/main/sender_constraining_access_tokens/index.md>) is a technique to
cryptographically bind personal access tokens to their owners. The tools to manage the client aspects of DPoP are
provided by this command.

The command generates a DPoP proof JWT that can be used alongside a Personal Access Token (PAT) to authenticate
to the GitLab API. It is valid for 5 minutes and will need to be generated again once it expires. Your SSH
private key will be used to sign the JWT. RSA, ed25519, and ECDSA keys are supported.


USAGE
  glab auth dpop-generate [flags]

FLAGS
  -h, --hostname string       The hostname of the GitLab instance to authenticate with (default "gitlab.com")
      --pat glab auth login   Personal Access Token (PAT) to generate a DPoP proof for. If this is not provided, the token set with glab auth login will be used. In the absence of both, there will be an error.
  -p, --private-key string    Location of the private SSH key on the local system.

INHERITED FLAGS
  --help   Show help for command

EXAMPLES
  # Generate a DPoP JWT for authentication to GitLab
  $ glab dpop-generate [flags]
  $ glab dpop-generate --private-key "~/.ssh/id_rsa" --pat "glpat-xxxxxxxxxxxxxxxxxxxx"
  # No PAT required if the user has previously used the glab auth login command with a PAT
  $ glab dpop-generate --private-key "~/.ssh/id_rsa"
  # Generate a DPoP JWT for another GitLab instance
  $ glab dpop-generate --private-key "~/.ssh/id_rsa" --hostname "https://gitlab.com"

LEARN MORE
  Use 'glab <command> <subcommand> --help' for more information about a command.

Types of changes

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to change)
  • Documentation
  • Chore (Related to CI or Packaging to platforms)
  • Test gap
Edited by Rohit Shambhuni

Merge request reports