Skip to content
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
d42b9a3
feat(docs): Enhance the catalyst rbac URI so it can be used as a gene…
stevenj Jan 17, 2025
e992aee
fix(rust): rename the kid_uri to just an id_uri to better reflect its…
stevenj Jan 17, 2025
5bad43a
fix(rust): remove cruft
stevenj Jan 17, 2025
42a4a99
feat(rust): New catalyst IdUri type to replace the more limited Kid
stevenj Jan 19, 2025
5961bdd
docs(docs): cleanup the project dict
stevenj Jan 19, 2025
22e0d29
docs(docs): Replace <key> with a concrete valid example public key
stevenj Jan 20, 2025
1299f97
docs(docs): Fix documentation inconsistencies
stevenj Jan 20, 2025
784ae1b
Update docs/src/architecture/08_concepts/rbac_id_uri/catalyst-id-uri.md
stevenj Jan 20, 2025
59a2ce4
fix(docs): Spelling issue
stevenj Jan 20, 2025
74d6fb5
Merge branch 'feat/cat-kid-to-cat-id' of github.com:input-output-hk/c…
stevenj Jan 20, 2025
5cda5d3
Update rust/catalyst-types/src/id_uri/mod.rs
stevenj Jan 20, 2025
9ea0364
Update docs/src/architecture/08_concepts/rbac_id_uri/catalyst-id-uri.md
stevenj Jan 20, 2025
a6ef2a6
Merge branch 'main' into feat/cat-kid-to-cat-id
stevenj Jan 20, 2025
f1303dc
fix(rust): Remove role and rotation from new as we should use `with_r…
stevenj Jan 20, 2025
40fc69a
Merge branch 'feat/cat-kid-to-cat-id' of github.com:input-output-hk/c…
stevenj Jan 20, 2025
a481394
fix(rust): Fail correctly if converting from &[u8] and the data isn't…
stevenj Jan 20, 2025
4435c5c
docs(rust): fix comment
stevenj Jan 21, 2025
70cb89d
docs(docs): add nsecs to project dictionary
stevenj Jan 21, 2025
fc39558
fix(rust): clamp a specific nonce, in case it was attempted to be set…
stevenj Jan 21, 2025
74e7881
Merge branch 'main' into feat/cat-kid-to-cat-id
stevenj Jan 22, 2025
1ab9e14
docs(rust): improve documentation of a number of public functions in …
stevenj Jan 23, 2025
994d79c
Merge branch 'main' into feat/cat-kid-to-cat-id
stevenj Jan 23, 2025
c8f7737
Merge branch 'main' into feat/cat-kid-to-cat-id
stevenj Jan 24, 2025
2562519
fix(rust): Fix doc test
stevenj Jan 24, 2025
c03ed5b
Merge branch 'feat/cat-kid-to-cat-id' of github.com:input-output-hk/c…
stevenj Jan 24, 2025
c3bc9a1
Merge branch 'main' into feat/cat-kid-to-cat-id
stevenj Jan 24, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .config/dictionaries/project.dic
Original file line number Diff line number Diff line change
Expand Up @@ -238,8 +238,8 @@ slotno
smac
stevenj
stringzilla
subsec
subnetwork
subsec
symlinkat
syscall
tacho
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
title: RBAC KID (Key Identifier) URI
arrange:
- kiduri.md
- catalyst-id-uri.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
---
Title: RBAC Key Identifier URI Specification
Title: RBAC Catalyst Identifier URI Specification
Category: Catalyst
Status: Proposed
Authors:
Expand All @@ -20,8 +20,7 @@ License: CC-BY-4.0
* [`authority` - `host`](#authority---host)
* [List of defined hosts](#list-of-defined-hosts)
* [`authority` - `userinfo`](#authority---userinfo)
* [Lists of defined subnetwork `userinfo` values](#lists-of-defined-subnetwork-userinfo-values)
* [Cardano](#cardano)
* [Example `userinfo` with a `hostname`](#example-userinfo-with-a-hostname)
* [`path`](#path)
* [Reference Implementation](#reference-implementation)
* [Test Vectors](#test-vectors)
Expand All @@ -33,39 +32,44 @@ License: CC-BY-4.0

## Abstract

Definition of a [URI] which allows for RBAC keys used for different purposes to be easily and
Definition of a [URI], which allows for RBAC keys used for different purposes to be easily and
unambiguously identified.

## Motivation: why is this CIP necessary?

There is a need to identify which Key from a RBAC registration was used to sign data.
There is a need to identify which RBAC Registration is referenced,
or which Key from a RBAC registration was used to sign data.
RBAC defines a universal keychain of different keys that can be used for different purposes.
They can be used not only for Signatures, but also Encryption.

Therefore, there needs to be an unambiguous and easy to lookup identifier to signify which key was
used for a particular purpose.
Sometimes all that is required is to identify the individual keychain.
Other times a specific key on the chain needs to be referenced.

This document defines a [URI] scheme to unambiguously define a particular key with reference to a
particular RBAC keychain.
Therefore, there needs to be an unambiguous and easy to lookup identifier to signify which keychain,
or key in a particular chain was used for a particular purpose.

This document defines a [URI] scheme to unambiguously define a keychain or a specific key within the keychain.

## Specification

### URI

The RBAC Kid is formatted using a [Universal Resource Identifier].
The Catalyst RBAC ID is formatted using a [Universal Resource Identifier].
Refer to [RFC3986] for the specification of the URI format.

### `scheme`

The [scheme](https://datatracker.ietf.org/doc/html/rfc3986#section-3.1) **MUST** be `kid.catalyst-rbac`;
The [scheme](https://datatracker.ietf.org/doc/html/rfc3986#section-3.1) **MUST** be `id.catalyst`.

When used as a Catalyst ID, where only catalyst IDs would be used, the scheme can be omitted.

### `authority`

The [authority](https://datatracker.ietf.org/doc/html/rfc3986#section-3.2) references the blockchain or network
the key was registered within.

It is perfectly valid for a Kid to reference a different network than the place where the Key is used.
For example, a `cardano` KID can be used to post documents to `IPFS`.
It is perfectly valid for an ID Uri to reference a different network than the place where the ID or Key is used.
For example, a `cardano` ID can be used to post documents to `IPFS`.
Its purpose is to define WHERE the key was registered, and nothing more.

The Authority will consist of a `host` and optional `userinfo`.
Expand All @@ -78,30 +82,43 @@ It **IS NOT** resolvable with **DNS**, and **IS NOT** a public host name.
It is used as a decentralized network identifier.
The consumer of the `KID` must be able to resolve these host names.

The hostname may have one or more subdomains which could specify side-chains of a particular network,
or test networks.

##### List of defined hosts

| `host` | Description |
| --- | --- |
| `cardano` | Cardano Blockchain |
| `preprod.cardano` | Preprod Cardano Blockchain test network |
| `preview.cardano` | Preview Cardano Blockchain test network |
| `midnight` | Midnight Blockchain |
| `ethereum` | Ethereum Blockchain |
| `cosmos` | Cosmos Blockchain |

This list is indicative of the host names that can be used, any hostname is valid provided it is
capable of storing catalyst RBAC registration keychains.

#### `authority` - `userinfo`

The [userinfo](https://datatracker.ietf.org/doc/html/rfc3986#section-3.2.1)
is used to distinguish a subnetwork from the primary main network.
The absence of `userinfo` is used to indicate the primary main network.
The [userinfo] is used to hold a user defined readable name that can be attached to the keychain.
It may contain an optional `nonce` which is separated from the user's name by a `:` and replaces a
traditional password used for HTTP basic authentication.

##### Lists of defined subnetwork `userinfo` values
Because the name is not unique, and is provided by the user, it is informational only.
A URI is identical, provided the hostname and path are the same, the [userinfo] does not play
a part in validating or finding the catalyst keychain being referenced.

###### Cardano
The `nonce` part contained in the `password` component of the username *MUST* be an integer,
and it is the number of seconds since 1970 UTC, when the Catalyst ID URI was generated.

| `userinfo` | Description |
| --- | --- |
| `preprod` | Cardano Pre-Production Network |
| `preview` | Cardano Preview Network |
| 0x<hex_number> | Cardano network identified by this magic number in hex |
Applications which use the `nonce` will define its use, anything that does not use the `nonce` will ignore it.

##### Example `userinfo` with a `hostname`

* `anne@cardano` - username `anne` no nonce.
* `blake:1737101079@midnight` - username `blake` with nonce 1737101079.
* `:173710179#ethereum` - no username with nonce 173710179.

### `path`

Expand All @@ -115,13 +132,16 @@ The overall `path` specification is: `<initial role0 key>/<role>/<rotation>#encr
* This does not change, even if the Initial Role 0 key is revoked.
* This allows for an unambiguous identifier for the RBAC keychain.
* It is not necessarily the key being identified.
* `<role>` - This is the Role number being used.
* `<role>` - *Optional* This is the Role number being used.
* It is a positive number, starting at 0, and no greater than 65535.
* `<rotation>` - This is the rotation of the defined role key being identified.
* If it is not defined, then its default value is 0.
* If it is not defined, there can be no `<rotation>` part of the path following.
* `<rotation>` - *Optional* This is the rotation of the defined role key being identified.
* It starts at 0 for the first published key for the role, and increments by one for each subsequent published rotation.
* This number refers to the published sequence of keys for the role in the RBAC registration keychain,
not the index used in the key derivation.
* It is positive and no greater than 65535.
* If not present, it defaults to 0.
* `#encrypt` - [Fragment](https://datatracker.ietf.org/doc/html/rfc3986#section-3.5)
disambiguates Encryption Public Keys from signing public keys.
* Roles can have 1 active public signing key, and 1 active public encryption key.
Expand All @@ -134,26 +154,48 @@ The first implementation will be Catalyst Voices.

## Test Vectors

* `kid.catalyst-rbac://cardano/<key>/0/0`
* `id.catalyst://cardano/<key>`
* A Signing key registered on the Cardano Main network.
* Role 0 - Rotation 0.
* `username` - undefined.
* `nonce` - undefined.
* In this example, it is identical to `<key>/0/0` or `<key>/0`.
* `id.catalyst://cardano/<key>/0`
* A Signing key registered on the Cardano Main network.
* Role 0 - Rotation 0.
* `username` - undefined.
* `nonce` - undefined.
* In this example, it is identical to `<key>/0/0` or `<key>`.
* `id.catalyst://gary@cardano/<key>/0/0`
* A Signing key registered on the Cardano Main network.
* Role 0 - Rotation 0.
In this example, it is exactly the same as the `<key>`.
* `kid.catalyst-rbac://preprod@cardano/<key>/7/3`
* `username` - `gary`.
* `nonce` - undefined.
* In this example, it is identical to `<key>` or `<key>/0`.
* `id.catalyst://faith@preprod@cardano/<key>/7/3`
* A Signing key registered on the Cardano pre-production network.
* Role 7 - Rotation 3.
The Key for Role 7, and its third published rotation
* `username` - `faith`
* `nonce` - undefined.
* The Key for Role 7, and its third published rotation
(i.e., the fourth key published, the first is the initial key, plus 3 rotations following it).
* `kid.catalyst-rbac://preprod@cardano/<key>/2/0#encrypt`
* `id.catalyst://faith:173710179@preprod@cardano/<key>/2/0#encrypt`
* A Public Encryption key registered on the Cardano pre-production network.
* Role 2 - Rotation 0.
The initially published Public Encryption Key for Role 2.
* `kid.catalyst-rbac://midnight/<key>/0/1`
* `username` - `faith`
* `nonce` - 173710179.
* The initially published Public Encryption Key for Role 2.
* `kid.catalyst-rbac://:173710179@midnight/<key>/0/1`
* A Signing key registered on the Midnight Blockchain Main network
* Role 0 - Rotation 1.
In this example, it is NOT the same as the `<key>`, as it identifies the first rotation after `<key>`.
* `username` - undefined.
* `nonce` - 173710179.
* In this example, it is NOT the same as the `<key>`, as it identifies the first rotation after `<key>`.
* `kid.catalyst-rbac://midnight/<key>/2/1#encrypt`
* A public encryption key registered on the Midnight Blockchain Main network.
* Role 2 - Rotation 1.
* `username` - undefined.
* `nonce` - 173710179.

## Rationale: how does this CIP achieve its goals?

Expand All @@ -178,3 +220,4 @@ This document is licensed under [CC-BY-4.0](https://creativecommons.org/licenses
[Universal Resource Identifier]: https://datatracker.ietf.org/doc/html/rfc3986
[RFC3986]: https://datatracker.ietf.org/doc/html/rfc3986
[Base64 URL]: https://datatracker.ietf.org/doc/html/rfc4648#section-5
[userinfo]: (https://datatracker.ietf.org/doc/html/rfc3986#section-3.2.1)
61 changes: 0 additions & 61 deletions rust/cardano-blockchain-types/deps.tmp

This file was deleted.

5 changes: 3 additions & 2 deletions rust/catalyst-types/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,10 @@ num-traits = "0.2.19"
orx-concurrent-vec = "3.1.0"
pallas-crypto = { version = "0.30.1", git = "https://github.com/input-output-hk/catalyst-pallas.git", rev = "9b5183c8b90b90fe2cc319d986e933e9518957b3" }
serde = { version = "1.0.217", features = ["derive"] }
thiserror = "2.0.9"
thiserror = "2.0.11"
base64-url = "3.0.0"
uuid = { version = "1.11.0", features = ["v4", "v7", "serde"] }
uuid = { version = "1.12.0", features = ["v4", "v7", "serde"] }
chrono = "0.4.39"

[dev-dependencies]
ed25519-dalek = { version = "2.1.1", features = ["rand_core"] }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,15 @@ use super::{key_rotation::KeyRotationError, role_index::RoleIndexError};

/// Errors that can occur when parsing a `KidUri`
#[derive(Display, Error, Debug)]
pub enum KidUriError {
pub enum IdUriError {
/// Invalid KID URI
InvalidURI(#[from] fluent_uri::error::ParseError),
/// Invalid Scheme, not a KID URI
InvalidURI(#[from] fluent_uri::error::ParseError<String>),
/// Invalid Scheme, not a ID URI
InvalidScheme,
/// Network not defined in URI
NoDefinedNetwork,
/// Invalid Nonce
InvalidNonce,
/// Path of URI is invalid
InvalidPath,
/// Role 0 Key in path is invalid
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,23 @@ pub enum KeyRotationError {
#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct KeyRotation(u16);

impl KeyRotation {
/// Default Role Index
pub const DEFAULT: KeyRotation = KeyRotation(0);

/// Is the `KeyRotation` the default value
#[must_use]
pub fn is_default(self) -> bool {
self == Self::DEFAULT
}
}

impl Default for KeyRotation {
fn default() -> Self {
Self::DEFAULT
}
}

impl From<u16> for KeyRotation {
fn from(value: u16) -> Self {
Self(value)
Expand Down
Loading
Loading