Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

docs: 466/hash-verification #512

Merged
merged 11 commits into from
Dec 19, 2024
33 changes: 24 additions & 9 deletions docs/astro.config.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -81,15 +81,30 @@ export default defineConfig({
},
{
label: 'Grant negotiation and authorization',
link: '/introduction/grants/'
},
{
label: 'Client keys',
link: '/introduction/client-keys/'
},
{
label: 'HTTP message signatures',
link: '/introduction/http-signatures/'
collapsed: true,

items: [
{
label: 'Overview',
link: '/introduction/grants/'
},
{
label: 'Identity providers',
link: '/introduction/idp/'
},
{
label: 'Client keys',
link: '/introduction/client-keys/'
},
{
label: 'HTTP message signatures',
link: '/introduction/http-signatures/'
},
{
label: 'Hash verification',
link: '/introduction/hash-verification/'
}
]
}
]
},
Expand Down
12 changes: 0 additions & 12 deletions docs/src/content/docs/introduction/grants.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -93,15 +93,3 @@ Operations on the APIs by a client require the client to have a valid access tok
:::note
An open-source implementation of an Open Payments resource server, called <LinkOut href='https://rafiki.dev'>Rafiki</LinkOut>, is currently in development.
:::

## Identity providers

An identity provider (IdP) is a system or service that manages user authentication, identity information, and consent. Open Payments requires any AS that issues <Tooltip content="A grant requiring explicit interaction/consent from the resource owner before an access token can be issued" client:load><span>interactive grants</span></Tooltip> be integrated with an IdP.

After an interactive grant request is initiated and the AS sets the session, the AS provides the client with the IdP URI to redirect the end-user to.

<Interactive />

:::tip[Reference implementation]
Rafiki provides a reference <LinkOut href='https://github.com/interledger/rafiki/tree/main/packages/auth'>authorization service</LinkOut> implementation that includes support for integration with an IdP.
:::
49 changes: 49 additions & 0 deletions docs/src/content/docs/introduction/hash-verification.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
---
title: Hash verification
---

import { CodeBlock, LinkOut, Tooltip } from '@interledger/docs-design-system'

Once a resource owner (RO) authorizes a client software, the authorization server (AS) will redirect the RO's [identity provider (IdP)](/introduction/idp/) to the finish URI if the client had provided an `interact.finish` object in the intial request. In order to secure this communication and verify that the redirect indeed emanated from the AS, the AS will provide a hash parameter in the request to the client's callback URI. The client **_must_** verify this hash.

## Hashing method

The hash base is generated by concatentating the following values in sequence using a single newline `(/n)` character to separate them:

1. `nonce` value sent by the client in the initial request.
2. `nonce` value returned from the AS after the initial grant request.
3. `interact_ref` returned from the AS in the interaction finish method.
4. The grant endpoint `uri` the client used to make its initial request.

The following example shows the four aforementioned components that make up the hash base. There is no padding or whitespace before or after each line and no trailing newline character.

<CodeBlock title="Example hash base">

```http
VJLO6A4CATR0KRO
MBDOFXG4Y5CVJCX821LH
4IFWWIKYB2PQ6U56NL1
https://server.example.com/tx
```

</CodeBlock>

The ASCII encoding of this string is hashed with the `sha-256` algorithm, which is the only hashing algorithm currently supported by Open Payments. The byte array from the hash function is then encoded using Base64 with no padding. The resultant string is the hash value.

Using our hash base string example above, the following is the `sha-256` encoded hash that uses the 256-bit SHA2 algorithm.

<CodeBlock title="SHA2 256-bit hash example">

```http
x-gguKWTj8rQf7d7i3w3UhzvuJ5bpOlKyAlVpLxBffY
```

</CodeBlock>

## Verifying hash

When the client receives a redirect from the AS, the AS will include the hash parameter in the response. The client must calculate this exact value by concatenating the fields referenced above and then applying the `sha-256` hashing algorithm. If the hash value matches the parameter sent by the AS, then the client can be certain the redirect emanated from the AS.
Comment on lines +43 to +45
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you think its valuable, we can also add a JS example:

function verifyHash(
  clientNonce,
  interactNonce,
  interactRef,
  authServerUrl,
  receivedHash
) {
  const data = `${clientNonce}\n${interactNonce}\n${interactRef}\n${authServerUrl}/`
  const hash = createHash('sha-256').update(data).digest('base64')

  return hash === receivedHash
}


## Further reading

For more information refer to the <LinkOut href='https://datatracker.ietf.org/doc/html/draft-ietf-gnap-core-protocol-20#name-calculating-the-interaction'>Calculating the interaction hash</LinkOut> section of the GNAP specification.
22 changes: 22 additions & 0 deletions docs/src/content/docs/introduction/idp.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
---
title: Identity providers
---

import {
CodeBlock,
LinkOut,
Tooltip,
Mermaid,
MermaidWrapper
} from '@interledger/docs-design-system'
import Interactive from '/src/partials/diagram-interactive-grant.mdx'

An identity provider (IdP) is a system or service that manages user authentication, identity information, and consent. Open Payments requires any authorization server (AS) that issues <Tooltip content="A grant requiring explicit interaction/consent from the resource owner before an access token can be issued" client:load><span>interactive grants</span></Tooltip> be integrated with an IdP.

After an interactive grant request is initiated and the AS sets the session, the AS provides the client with the IdP URI to redirect the end-user to.

<Interactive />

:::tip[Reference implementation]
Rafiki provides a reference <LinkOut href='https://rafiki.dev/integration/services/auth-service/'>authorization service</LinkOut> implementation that includes support for integration with an IdP.
:::
2 changes: 1 addition & 1 deletion docs/src/content/docs/introduction/op-flow.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,7 @@ Similarly, the client can provide the end-user with details about a specific <Li

This diagram brings the aforementioned concepts together, except for getting transaction history, to present a full transaction sequence without delving too deeply into the contents of each request and response. A link to view a larger version of the diagram is provided at the bottom of the page.

As shown below, both the sender and the recipient's ASEs must operate their own authorization and resource servers. Grant requests for incoming payment and quote resources are typically non-interactive. A grant request for an outgoing payment resource requires explicit consent from the sender (e.g., the client's end user), which is obtained through the sender's [identity provider](/introduction/grants#identity-providers).
As shown below, both the sender and the recipient's ASEs must operate their own authorization and resource servers. Grant requests for incoming payment and quote resources are typically non-interactive. A grant request for an outgoing payment resource requires explicit consent from the sender (e.g., the client's end user), which is obtained through the sender's [identity provider](/introduction/idp/).

More information about grant interaction flows can be found in the [Grant negotiation and authorization](/introduction/grants) page.

Expand Down
2 changes: 1 addition & 1 deletion docs/src/content/docs/resources/glossary.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ Open Payments is an open RESTful API and an API standard that enables clients to

## Outgoing payment resource

An [outgoing payment resource](/introduction/op-concepts/#outgoing-payment) is an object created by the sender's ASE, on their resource server, that represents a payment being sent by an entity. This resource contains information about the outgoing payment, such as the amount, currency, receiver's wallet address, and payment status. Outgoing payment resources require explicit [consent](/introduction/grants/#identity-providers) from the sender before the resource can be created.
An [outgoing payment resource](/introduction/op-concepts/#outgoing-payment) is an object created by the sender's ASE, on their resource server, that represents a payment being sent by an entity. This resource contains information about the outgoing payment, such as the amount, currency, receiver's wallet address, and payment status. Outgoing payment resources require explicit [consent](/introduction/idp/) from the sender before the resource can be created.

## Quote resource

Expand Down
2 changes: 1 addition & 1 deletion docs/src/content/docs/snippets/outgoing-get.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
title: Get an outgoing payment
---

import { Disclosure, CodeBlock, LinkOut } from '@interledger/docs-design-system'
import { CodeBlock, LinkOut } from '@interledger/docs-design-system'
import { Tabs, TabItem } from '@astrojs/starlight/components'
import ChunkedSnippet from '/src/components/ChunkedSnippet.astro'
import Begin from '/src/partials/before-you-begin.mdx'
Expand Down
2 changes: 1 addition & 1 deletion docs/src/content/docs/snippets/token-revoke.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
title: Revoke an access token
---

import { Disclosure, CodeBlock, LinkOut } from '@interledger/docs-design-system'
import { CodeBlock, LinkOut } from '@interledger/docs-design-system'
import { Tabs, TabItem } from '@astrojs/starlight/components'
import ChunkedSnippet from '/src/components/ChunkedSnippet.astro'
import Begin from '/src/partials/before-you-begin.mdx'
Expand Down
2 changes: 1 addition & 1 deletion docs/src/content/docs/snippets/token-rotate.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
title: Rotate an access token
---

import { Disclosure, CodeBlock, LinkOut } from '@interledger/docs-design-system'
import { CodeBlock, LinkOut } from '@interledger/docs-design-system'
import { Tabs, TabItem } from '@astrojs/starlight/components'
import ChunkedSnippet from '/src/components/ChunkedSnippet.astro'
import Begin from '/src/partials/before-you-begin.mdx'
Expand Down
Loading