[OAUTH-WG] DPoP Binding JWT proposal

Dick Hardt <dick.hardt@gmail.com> Fri, 06 November 2020 22:12 UTC

Return-Path: <dick.hardt@gmail.com>
X-Original-To: oauth@ietfa.amsl.com
Delivered-To: oauth@ietfa.amsl.com
Received: from localhost (localhost [127.0.0.1]) by ietfa.amsl.com (Postfix) with ESMTP id 8A9AF3A0DB2 for <oauth@ietfa.amsl.com>; Fri, 6 Nov 2020 14:12:48 -0800 (PST)
X-Virus-Scanned: amavisd-new at amsl.com
X-Spam-Flag: NO
X-Spam-Score: -2.096
X-Spam-Level:
X-Spam-Status: No, score=-2.096 tagged_above=-999 required=5 tests=[BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, FREEMAIL_FROM=0.001, HTML_FONT_LOW_CONTRAST=0.001, HTML_MESSAGE=0.001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001, URIBL_BLOCKED=0.001] autolearn=ham autolearn_force=no
Authentication-Results: ietfa.amsl.com (amavisd-new); dkim=pass (2048-bit key) header.d=gmail.com
Received: from mail.ietf.org ([4.31.198.44]) by localhost (ietfa.amsl.com [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id M_gpVniIGWfY for <oauth@ietfa.amsl.com>; Fri, 6 Nov 2020 14:12:46 -0800 (PST)
Received: from mail-lf1-x136.google.com (mail-lf1-x136.google.com [IPv6:2a00:1450:4864:20::136]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by ietfa.amsl.com (Postfix) with ESMTPS id 5C4583A0DAD for <oauth@ietf.org>; Fri, 6 Nov 2020 14:12:46 -0800 (PST)
Received: by mail-lf1-x136.google.com with SMTP id f9so4013883lfq.2 for <oauth@ietf.org>; Fri, 06 Nov 2020 14:12:46 -0800 (PST)
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=mime-version:from:date:message-id:subject:to; bh=JRwAlbW9pwadt5o9BtGPomG7s2nigpObjZBKRLfydHo=; b=dTnl6pYw9bnfLHHwlyASqmIASAz8kLT4iJEkwTA1sTzQ14h/nN2yE+NXN6MYRG1Qzg 6fk/OMcqWH22LrNX5//vw8BoSVPcN1kaPShpXJ1e0X4BeRaQBc22G2tuxPX7YbfHHZzo bLKiXwIfLptNYzfXexJHZqy7wBlB/qvLWmSnaN3n6MIXi4fKOTN+qdormKR03y85DcFt C3az0HR10u/kdXMxkLLq38ZBkHQUV1YC7polCJrwZHZMoULxpkPoyHXjELIQXlDYlQ9E OU5iJkfR1RX/YCdYahw1zwq3EPSYGe25QGcytuBYX+SaWPidCGo+p3BQ1ySxCN+UIKg8 hbsw==
X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:mime-version:from:date:message-id:subject:to; bh=JRwAlbW9pwadt5o9BtGPomG7s2nigpObjZBKRLfydHo=; b=fKV4QkOolbMFXR+75A+d9l/fRGn8GycJb7CK0czHnXuRpWdRiYxxl48RSdIi9gvAoV DXqHHdev84xqlotFISURb0xktzfJ/WcmDJMxEv+r9D760mjL5qsw9GyVCQ1XH9JlaNz7 TY3N2Otfu40WOZuvm47dlZgDuCYvEHNu2bgPjnJIxPAFKyU6QvwBxC5jso/P8XVVCA+5 41EPm7sap44O9kmgegmOxIBO64iIjZkrhSrOPuSJlOmNo5k8v6lEE1BjqZQTcVu2JVlr hnvomB5J83QspzYctJU0x3IwKblVW4JvXk/HxFnX7K+7+BZcKePawAIDlY1efX2OqVaA 5qww==
X-Gm-Message-State: AOAM532rXkzC+of9YgrYgLJuFuIo2dr8LdBKrpk+tiTImsctchG3V/Y0 kJFzcHXpHVupqoSqDS4E3hS9dOhmQVwoUryC6ay/n3BOZKG5ig==
X-Google-Smtp-Source: ABdhPJzlEM8wzMnuHFnscpX5cKh2uURwPaLDUWs+XUTfakGKgPPFXvRkdaH3h/FfD1W1WvOYX0PoqIvNoAS90LKnKPQ=
X-Received: by 2002:a19:740c:: with SMTP id v12mr1520874lfe.221.1604700764062; Fri, 06 Nov 2020 14:12:44 -0800 (PST)
MIME-Version: 1.0
From: Dick Hardt <dick.hardt@gmail.com>
Date: Fri, 6 Nov 2020 14:12:07 -0800
Message-ID: <CAD9ie-t6-fN+r75AkJCkfQOLWSYJYQsUXrKz88pK+bsr7KGnQQ@mail.gmail.com>
To: oauth@ietf.org
Content-Type: multipart/alternative; boundary="00000000000003485105b377837b"
Archived-At: <https://mailarchive.ietf.org/arch/msg/oauth/zGW5fmEi52rSIOcaty4Mkye-_n8>
Subject: [OAUTH-WG] DPoP Binding JWT proposal
X-BeenThere: oauth@ietf.org
X-Mailman-Version: 2.1.29
Precedence: list
List-Id: OAUTH WG <oauth.ietf.org>
List-Unsubscribe: <https://www.ietf.org/mailman/options/oauth>, <mailto:oauth-request@ietf.org?subject=unsubscribe>
List-Archive: <https://mailarchive.ietf.org/arch/browse/oauth/>
List-Post: <mailto:oauth@ietf.org>
List-Help: <mailto:oauth-request@ietf.org?subject=help>
List-Subscribe: <https://www.ietf.org/mailman/listinfo/oauth>, <mailto:oauth-request@ietf.org?subject=subscribe>
X-List-Received-Date: Fri, 06 Nov 2020 22:12:49 -0000

Hello

After reviewing the DPoP spec, and reflecting on implementations I have
worked with, I wanted to see if there was interest in a DPoP Binding JWT.

The use case is to enable existing deployments to add support for DPoP
without having to replace their existing refresh token and access tokens,
and the processing of them as the DPoP Binding JWT processing can be added
as an independent software layer.

The processing overhead is minimized as the DPoP Binding JWT
verification can be cached for an access token,
adding only one JWT verification for the lifetime of the access token.

DPoP Binding JWTs using asymmetric cryptographic algorithms, provide the
increased security of public / private key for existing deployments using
access tokens signed with shared secrets such as HMAC.

/Dick


*X. DPoP Binding JWT*
    Deployments that do not want to modify their existing access tokens or
resource tokens to contain
    the DPoP thumbprint can include DPoP Binding JWTs in the response from
the AS and present them in
    calls to the RS. A DPoP Binding JWT contains the DPoP thumbprint and a
hash of the access token
    or refresh token, and is signed by the AS.

    The use of DPoP Binding JWTs enables existing deployments to add
proof-of-possession assurance to
    existing deployments by adding a middle layer service or software
without modifying the processing
    of refresh tokens or access tokens.



*X.1 DPoP Binding JWT Syntax*
    * "typ": type header, value "dpop-binding+jwt"

    * "jti": unique id
    * "iat": time created
    * "jkt": JWK SHA-256 Thumbprint of the DPoP public key

    If binding an access token
        * "ath": SHA-256 hash of the access token

    If binding an refresh token
        * "rth": SHA-256 hash of the refresh token

    Example DPoP Binding JWT for an access token:

    {
        "typ":"dpop-binding+jwt",
        "alg":"ES256",
        "jwk": {
        "kty":"EC",
        "x":"l8tFrhx-34tV3hRICRDY9zCkDlpBhF42UQUfWVAWBFs",
        "y":"9VE4jf_Ok_o64zbTTlcuNJajHmt6v9TDVrU0CdvGRDA",
        "crv":"P-256"
        }
    }.{
        "jti":"-BwC3ESc6acc2lTc",
        "iat":1562262616,
        "jkt":"0ZcOCORZNYy-DWpqq30jZyJGHTN0d2HglBV3uiguA4I",
        "ath":"N0d2HglBV3uiguA4I0ZcOCORZNYy-DWpqq30jZyJGHT"
    }



*X.2 Checking DPoP Bindings*
    Check the DPoP Binding JWT is valid
    Check the DPoP Binding JWT "jkt" value matches the thumbprint of the
DPoP public key
    Check the DPoP Binding JWT "ath" value matches the SHA-256 hash of the
access token
      or
    Check the DPoP Binding JWT "rth" value matches the SHA-256 hash of the
refresh token


*X.3 Token Response*
    The AS sets the "token_type" parameter to "DPoP-Binding".
    The AS returns the DPoP Binding JWT for the access token in the
"access_token_binding" parameter,
    and the DPoP Binding JWT for the refresh token in the
"refresh_token_binding" parameter.

     HTTP/1.1 200 OK
     Content-Type: application/json;charset=UTF-8
     Cache-Control: no-store
     Pragma: no-cache

     {
       "access_token":"2YotnFZFEjr1zCsicMWpAA",
       "access_token_binding":"eyJ0eXAiOiJkcG9w....",
       "token_type":"DPoP-Binding",
       "expires_in":3600,
       "refresh_token":"tGzv3JOkF0XG5Qx2TlKWIA"
       "refresh_token_binding":"eyJ0eXAiOiJkcG9w....."
       "example_parameter":"example_value"
     }


*X.4 Resource access*
    The client presents the access token DPoP Binding JWT in the
"DPoP-Binding" HTTP header.

    GET /protectedresource HTTP/1.1
    Host: resource.example.org
    Authorization: DPoP eyJhbGciOiJFUzI1NiIsImtpZCI6IkJlQUxrYiJ9.eyJzdWI
        iOiJzb21lb25lQGV4YW1wbGUuY29tIiwiaXNzIjoiaHR0cHM6Ly9zZXJ2ZXIuZXhhbX
        BsZS5jb20iLCJhdWQiOiJodHRwczovL3Jlc291cmNlLmV4YW1wbGUub3JnIiwibmJmI
        joxNTYyMjYyNjExLCJleHAiOjE1NjIyNjYyMTYsImNuZiI6eyJqa3QiOiIwWmNPQ09S
        Wk5ZeS1EV3BxcTMwalp5SkdIVE4wZDJIZ2xCVjN1aWd1QTRJIn19.vsFiVqHCyIkBYu
        50c69bmPJsj8qYlsXfuC6nZcLl8YYRNOhqMuRXu6oSZHe2dGZY0ODNaGg1cg-kVigzY
        hF1MQ
    DPoP: eyJ0eXAiOiJkcG9wK2p3dCIsImFsZyI6IkVTMjU2IiwiandrIjp7Imt0eSI6Ik
        VDIiwieCI6Imw4dEZyaHgtMzR0VjNoUklDUkRZOXpDa0RscEJoRjQyVVFVZldWQVdCR
        nMiLCJ5IjoiOVZFNGpmX09rX282NHpiVFRsY3VOSmFqSG10NnY5VERWclUwQ2R2R1JE
        QSIsImNydiI6IlAtMjU2In19.eyJqdGkiOiJlMWozVl9iS2ljOC1MQUVCIiwiaHRtIj
        oiR0VUIiwiaHR1IjoiaHR0cHM6Ly9yZXNvdXJjZS5leGFtcGxlLm9yZy9wcm90ZWN0Z
        WRyZXNvdXJjZSIsImlhdCI6MTU2MjI2MjYxOH0.lNhmpAX1WwmpBvwhok4E74kWCiGB
        NdavjLAeevGy32H3dbF0Jbri69Nm2ukkwb-uyUI4AUg1JSskfWIyo4UCbQ
    DPoP-Binding: eyJ_an_example_DPoP_binding_JWT_0eXAiOiJkcG9wK2p3dCIsI
        VDIiwieCI6Imw4dEZyaHgtMzR0VjNoUklDUkRZOXpDa0RscEJoRjQyVVFVZldWQVdCR
        nMiLCJ5IjoiOVZFNGpmX09rX282NHpiVFRsY3VOSmFqSG10NnY5VERWclUwQ2R2R1JE
        QSIsImNydiI6IlAtMjU2In19.eyJqdGkiOiJlMWozVl9iS2ljOC1MQUVCIiwiaHRtIj
        oiR0VUIiwiaHR1IjoiaHR0cHM6Ly9yZXNvdXJjZS5leGFtcGxlLm9yZy9wcm90ZWN0Z
        WRyZXNvdXJjZSIsImlhdCI6MTU2MjI2MjYxOH0.lNhmpAX1WwmpBvwhok4E74kWCiGB
        NdavjLAeevGy32H3dbF0Jbri69Nm2ukkwb-uyUI4AUg1JSskfWIyo4UCbQ



ᐧ