Categorygithub.com/AxisCommunications/go-dpop
modulepackage
1.1.0
Repository: https://github.com/axiscommunications/go-dpop.git
Documentation: pkg.go.dev

# README

go-dpop

Go Reference Coverage Status

OAuth 2.0 Demonstrating Proof of Possession (DPoP)

This package tries to implement RFC-9449

Supported key algorithms

Supported:

  • ES256, ES384, ES521
  • RS256, PS256
  • Ed25519

How to use

Authorization server

An authorization server needs to parse the incoming proof in order to associate the public key of the proof with the bound access token.
It should parse the proof to ensure that the sender of the proof has access to the private key.

import "github.com/AxisCommunications/go-dpop"

proof, err := dpop.Parse(proofString, dpop.POST, &httpUrl, dpop.ParseOptions{
    Nonce:      "",
    TimeWindow: &duration,
  })
// Check the error type to determine response
if err != nil {
  if ok := errors.Is(err, dpop.ErrInvalidProof); ok {
    // Return 'invalid_dpop_proof'
  }
}

// proof is valid, get public key to associate with access token
jkt := proof.PublicKey()

// Continue

Resource server

Resource servers need to do the same proof validation that authorization servers do but also check that the proof and access token are bound correctly.

import "github.com/AxisCommunications/go-dpop"

proof, err := dpop.Parse(proofString, dpop.POST, &httpUrl, dpop.ParseOptions{
    Nonce:      "",
    TimeWindow: &duration,
  })
// Check the error type to determine response
if err != nil {
  if ok := errors.Is(err, dpop.ErrInvalidProof); ok {
    // Return 'invalid_dpop_proof'
  }
}

// Hash the token with base64 and SHA256
// Get the access token JWT (introspect if needed)
// Parse the access token JWT and verify the signature

err = proof.Validate(accessTokenHash, accessTokenJWT)
// Check the error type to determine response
if err != nil {
  if ok := errors.Is(err, dpop.ErrInvalidProof); ok {
    // Return 'invalid_dpop_proof'
  }
  if ok := errors.Is(err, dpop.ErrIncorrectAccessTokenClaimsType); ok {
    // Return 'invalid_token'
  }
}

// Continue

Client

A client can generate proofs that authorization and resource servers can validate.

import "github.com/AxisCommunications/go-dpop"

// Setup the claims of the proof
claims := &dpop.ProofTokenClaims{
  RegisteredClaims: &jwt.RegisteredClaims{
    Issuer:    "test",
    Subject:   "sub",
    IssuedAt:  jwt.NewNumericDate(time.Now()),
    ExpiresAt: jwt.NewNumericDate(time.Now().Add(time.Minute)),
    ID:        "id",
  },
  Method: dpop.POST,
  URL:    "https://server.example.com/token",
}

// Create a key-pair to be used for signing
privateKey, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
if err != nil {
  ...
}

// Create a signed proof string
proofString, err := dpop.Create(jwt.SigningMethodES256, claims, privateKey)
if err != nil {
  ...
}

// Send the proof string in the 'DPoP' header to the server

Note on HMAC

Although this package can in theory support symmetric keys the DPoP draft does not allow private keys to be sent in the proof jwk header. As a symmetric key has no public key cryptography it can not be included in the proof, hence why it is unsupported.

# Packages

No description provided by the author

# Functions

Creates a DPoP proof for the given claims.
Parse translates a DPoP proof string into a JWT token and parses it with the jwt package (github.com/golang-jwt/jwt/v5).

# Constants

HTTP method supported by the package.
No description provided by the author
No description provided by the author
HTTP method supported by the package.
HTTP method supported by the package.
HTTP method supported by the package.
HTTP method supported by the package.
HTTP method supported by the package.
POST
HTTP method supported by the package.
HTTP method supported by the package.
HTTP method supported by the package.

# Variables

The proof 'ath' claim does not match bound access token.
The proof has expired.
The proof is issued too far into the future.
The bound access token claims are not of correct type.
The proof claims are not of correct type.
The `htm` and `htu` headers of the proof target the wrong resource.
The proof 'jwk' public header does not match supplied jkt.
If the nonce was not provided a `ErrIncorrectNonce` error is returned.
If proof validation failed for some reason a `ErrInvalidProof` error is returned.
The bound token 'jkt' claim does not match public key in proof.
The proof missing the `ath` claim.
The claims of the DPoP proof are invalid.
The proof is missing the `jwk` public key header.
The proof public key has an unsupported curve.
The `typ` header of the proof is invalid.
The proof uses an unsupported key algorithm.

# Structs

These claims contains fields that are required to be present in bound access tokens.
No description provided by the author
ParseOptions and its contents are optional for the Parse function.
Represents a DPoP proof, if acquired through the Parse function it should be a valid DPoP proof.
These claims contains the standard fields of a DPoP proof claim.

# Interfaces

This interface allows for custom claims to be used in bound tokens.
This interface allows for custom claims to be used in proof tokens.

# Type aliases

HTTPVerb is a convenience for determining the HTTP method of a request.