← Back to list

Security in OAuth2 : non-repudiation and integrity

Non-repudiation is a critical security property that ensures an actor cannot deny having sent a message or performed an action. In…

Kunal Sinha in CodeToDeploy · 2025-07-08 02:48 · 50 claps · 3.6 min read paywalled
#fapi #oauth #ai-agent-security #authentication #oauth2
Open on Medium ↗
Wiki topics: AGT · AI Agents

Security in OAuth2 : non-repudiation and integrity

Non-repudiation is a critical security property that ensures an actor cannot deny having sent a message or performed an action. In trustworthy security systems, all parties must be held accountable for their actions during message exchanges. In OAuth flows, multiple parties interact throughout the authorization process. To maintain a reliable audit trail, we must ensure that no party can deny their participation in these exchanges. This article explores how to implement non-repudiation and integrity controls in OAuth2 systems.

🚀 Top Remote Tech Jobs — $50–$120/hr

🔥 Multiple Roles Open Hiring Experienced Talent (3+ years) Only.

  • Frontend / Backend / Full Stack
  • Mobile (iOS/Android)
  • AI / ML
  • DevOps & Cloud

Opportunities Fill FAST — Early Applicants Get Priority! 👉 **Apply Here**

Non-repudiation in the front-channel (Client to Authorization Server)

We previously discussed PAR (Pushed Authorization Requests), which allows the client to submit query details using the back-channel and retrieve a request_uri for use in the authorization grant flow. JAR (JWT Authorization Requests) takes this a step further — the signature on the JAR provides additional, cryptographically binding proof that the content of the request was indeed generated by the registered client, complementing the TLS-level client authentication of PAR. JAR may also be encrypted.

The most important aspect of JAR is that it offers non-repudiation for the client. Since the JWT content is digitally signed by the client, the client cannot later deny having made that specific authorization request with those specific parameters. This capability is crucial for auditing and accountability in high-security or regulated environments. Note that use of PAR is optional and the jwt token may be used directly against the query param if the purpose is to enforce non-repudiation only. An example: https://authoziation-server.com/authorize?client_id=CLIENT_ID&request=....jwt_token...

Non-repudiation from Authorization server to client for response code

JARM (JWT Authorization Response Mode) follows a similar approach. The authorization server packages the authorization code, state parameter, and other necessary values into a JWT token and digitally signs it. The client can then unpack the JWT token, validate the signature, and extract the values.

This ensures that the authorization server cannot later deny having issued that specific authorization response, providing non-repudiation for the server-to-client communication in the OAuth flow.

Non-repudiation between Authorization Server and Resource Server

An Authorization Server (AS) is responsible for issuing tokens. A Resource Server (RS) may want to validate the presented token to get details about it while ensuring that it came from the AS — with proof that can be verified later. While the fact that the token is issued by the AS itself ensures the action is non-repudiable, it is difficult to prove later in the absence of logging since the access token may not be available later.

To solve this, the token introspection endpoint may be used to request a JWT along with the response as defined in RFC 9701. The Resource Server uses either client credentials or a JWT signed by its private key to authenticate itself to the Authorization Server and present the token for introspection using the accept header: application/token-introspection+jwt. The Authorization Server returns token details in a JWT that's signed by the AS's private key.

The Resource Server may call the token introspection endpoint as follows:

POST /oauth2/introspect HTTP/1.1
Host: auth.example.com
Authorization: Basic <Base64(client_id:client_secret)>
Content-Type: application/x-www-form-urlencoded
Accept: application/token-introspection+jwt

token=eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9...
token_type_hint=access_token

In response, the AS returns a JWT with the following structure:

{ 
"iss" : "authorization_server"
"aud" : "resource_server"
"iat" : ...
"token_introspection" : {
  "active": true,
  "scope": "read write",
  "client_id": "abc123",
  "exp": 1712345678,
  "sub": "user123",
  "aud": ["api.example.com"],
  "iss": "https://auth.example.com",
  "token_type": "Bearer"
}
}

This JWT is digitally signed by the Authorization Server. For non-repudiation purposes, the Resource Server can log this JWT token string for later audit and verification.

Non-repudiation between Client and Resource Server

This relies on the FAPI 2.0 Message Signing Profile, which directly uses RFC 9421 HTTP Message Signatures. Both the client and resource server can digitally sign their messages, allowing the receiving party to cryptographically validate the signature. This ensures that neither party can later deny having sent specific requests or responses.

This capability is particularly valuable in financial and high-value scenarios where comprehensive audit trails are essential for regulatory compliance and dispute resolution.

An example of request from client to RS

POST /payments HTTP/1.1
Host: api.bank.example
Date: Mon, 07 Jul 2025 14:45:00 GMT
Content-Type: application/json
Content-Digest: sha-256=:j0/n7v8k1l2m3o4p5q6r7s8t9u0v1w2x3y4z5a6b7c8d9e0f=:
Authorization: Bearer eyJhbGciOiJSUzI1NiIsImtpZCI6InNvbWUtcmFuZG9tLWtpZCJ9.eyJ...[YOUR_ACCESS_TOKEN_JWT]...
Signature-Input: sig1=("@method" "@target-uri" "host" "date" "content-digest" "content-type" "authorization");created=1720373100;alg="rsa-pss-sha256";keyid="client-app-key-xyz"
Signature: sig1=:MFAwDgYJKoZIhvcNAQEEBQADzQQAwH4Gg0wIBAcEAwH4Gw0MGAgRgwMDA==[YOUR_DIGITAL_SIGNATURE_BASE64URL]==:

{
    "toAccount": "GB12CDFG45678901234567",
    "amount": {
        "value": 100.00,
        "currency": "GBP"
    },
    "reference": "Online Payment #12345"
}

Thank you for being a part of the community

Before you go:

👉 Be sure to clap and follow the writer ️👏️️

👉 Follow us: **X | [Medium](https://medium.com/codetodeploy)**

👉 CodeToDeploy Tech Community is live on Discord — **Join now!**

👉 Follow our publication, CodeToDeploy

Note: This Post may contain affiliate links.


메타데이터
post_id
2f13de995071
slug
security-in-oauth2-non-repudiation-and-integrity-2f13de995071
url
https://medium.com/codetodeploy/security-in-oauth2-non-repudiation-and-integrity-2f13de995071
canonical_url
https://medium.com/codetodeploy/security-in-oauth2-non-repudiation-and-integrity-2f13de995071
author_url
https://medium.com/@sinha.k
status
ok
fetched_at
2026-06-25 12:15:08