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

Open
wants to merge 10 commits into
base: main
Choose a base branch
from
5 changes: 2 additions & 3 deletions docs/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,6 @@ Refer to the Starlight documentation on [authoring content](https://starlight.as
We have extracted some of the commonly repeated patterns within the documentation pages into custom docs components that can be reused. There are components which are shared across all our Starlight documentation sites and those which are specific to this project only. This will determine what the import path is.

- CodeBlock (Shared)
- Disclosure (Shared)
- Hidden (Shared)
- LargeImg (Shared)
- LinkOut (Shared)
Expand All @@ -72,10 +71,10 @@ We have extracted some of the commonly repeated patterns within the documentatio
- [FullSnippet](#fullsnippet-component) (Project-specific)
- [ChunkedSnippet](#chunkedsnippet-component) (Project-specific)

For the shared components, if you are using both `CodeBlock` and `Disclosure` on the same page, you can import them both like so:
For the shared components, if you are using both `CodeBlock` and `Hidden` on the same page, you can import them both like so:

```jsx
import { CodeBlock, Disclosure } from '@interledger/docs-design-system'
import { CodeBlock, Hidden } from '@interledger/docs-design-system'
```

For more information about importing things in Javascript, please refer to [import on MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/import).
Expand Down
33 changes: 24 additions & 9 deletions docs/astro.config.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -69,15 +69,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.
:::
45 changes: 45 additions & 0 deletions docs/src/content/docs/introduction/hash-verification.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
---
title: Hash verification
---

import { CodeBlock, LinkOut } 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. 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.
Copy link
Contributor

Choose a reason for hiding this comment

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

the authorization server (AS) will redirect

even though its probably the most common use case, the AS will redirect only if the client provided an interact.finish object.

Copy link
Contributor

Choose a reason for hiding this comment

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

I think we need to add a small section about how the client actually would do verification: by generating the hash using the components below, and comparing it to the provided value in the final redirect


## 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 algorithm specified in the `hash_method` parameter under the `finish` key of the interaction finish request. The byte array from the hash function is then encoded using Base64 with no padding. The resultant string is the hash value.

Unless specified by the client in the initial request, the `hash_method` will default to `sha-256`. If the client specifies the `hash_method`, the `hash_method` **_must_** be one of the hash name strings defined in the <LinkOut href='https://www.iana.org/assignments/named-information/named-information.xhtml#hash-alg'>IANA Named Information Hash Algorithm Registry</LinkOut>.
Copy link
Contributor

Choose a reason for hiding this comment

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

We can say that Open Payments uses sha-256 only (even though GNAP is more flexible)


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>

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://github.com/interledger/rafiki/tree/main/packages/auth'>authorization service</LinkOut> implementation that includes support for integration with an IdP.
:::
Copy link
Contributor

Choose a reason for hiding this comment

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

Let's link to the Rafiki docs?

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/grant-continue.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
title: Continue a grant request
---

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/grant-create.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
title: Create a grant request
---

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/incoming-create.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
title: Create an incoming 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/incoming-list.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
title: List incoming payments
---

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/outgoing-create.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
title: Create 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/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/outgoing-list.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
title: List outgoing payments
---

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/quote-create.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
title: Create a quote
---

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/quote-get.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
title: Get a quote
---

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
2 changes: 1 addition & 1 deletion docs/src/content/docs/snippets/wallet-get-keys.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
title: Get keys bound to a wallet address
---

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
15 changes: 1 addition & 14 deletions docs/src/partials/code-snippets-template.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
title: Change this title
---

import { Disclosure, CodeBlock } from '@interledger/docs-design-system'
import { CodeBlock } from '@interledger/docs-design-system'
import { Tabs, TabItem } from '@astrojs/starlight/components'
import FullSnippet from '/src/components/FullSnippet.astro'
import ChunkedSnippet from '/src/components/ChunkedSnippet.astro'
Expand Down Expand Up @@ -30,19 +30,6 @@ import Ts from '/src/partials/ts-prerequisites.mdx'
</TabItem>
</Tabs>

<Disclosure toggleText='View full source' client:load>

Delete the contents of this disclosure and replace it with a link to the raw source
file like so:

```html
<FullSnippet
source="https://raw.githubusercontent.com/interledger/open-payments-snippets/main/token/token-rotate.ts"
/>
```

</Disclosure>

## References

- [Link to concept page(s)]()
Expand Down
6 changes: 3 additions & 3 deletions docs/src/partials/js-prerequisites.mdx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { LinkOut, Disclosure } from '@interledger/docs-design-system'

<Disclosure toggleText='Prerequisites' client:load>

<details>
<summary>Prerequisites</summary>
- Node 18 or higher
- A package manager such as NPM or PNPM
- <LinkOut href='https://www.npmjs.com/package/@interledger/open-payments'>
Expand All @@ -12,4 +12,4 @@ import { LinkOut, Disclosure } from '@interledger/docs-design-system'

Add `"type": "module"` to `package.json`

</Disclosure>
</details>
8 changes: 4 additions & 4 deletions docs/src/partials/ts-prerequisites.mdx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { LinkOut, Disclosure } from '@interledger/docs-design-system'

<Disclosure toggleText='Prerequisites' client:load>
import { LinkOut } from '@interledger/docs-design-system'

<details>
<summary>Prerequisites</summary>
- Node 18
- A package manager such as NPM or PNPM
- <LinkOut href='https://www.npmjs.com/package/@interledger/open-payments'>
Expand All @@ -24,4 +24,4 @@ Add the following to `tsconfig.json`
}
```

</Disclosure>
</details>
Loading