Skip to content

Commit 42a4a99

Browse files
committed
feat(rust): New catalyst IdUri type to replace the more limited Kid
1 parent 5bad43a commit 42a4a99

File tree

7 files changed

+422
-82
lines changed

7 files changed

+422
-82
lines changed

docs/src/architecture/08_concepts/rbac_id_uri/catalyst-id-uri.md

Lines changed: 16 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ License: CC-BY-4.0
3232

3333
## Abstract
3434

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

3838
## Motivation: why is this CIP necessary?
@@ -42,7 +42,7 @@ or which Key from a RBAC registration was used to sign data.
4242
RBAC defines a universal keychain of different keys that can be used for different purposes.
4343
They can be used not only for Signatures, but also Encryption.
4444

45-
Sometimes all that is required is to identify the individual key chain.
45+
Sometimes all that is required is to identify the individual keychain.
4646
Other times a specific key on the chain needs to be referenced.
4747

4848
Therefore, there needs to be an unambiguous and easy to lookup identifier to signify which keychain,
@@ -54,19 +54,21 @@ This document defines a [URI] scheme to unambiguously define a keychain or a spe
5454

5555
### URI
5656

57-
The Catalyst RBAC Id is formatted using a [Universal Resource Identifier].
57+
The Catalyst RBAC ID is formatted using a [Universal Resource Identifier].
5858
Refer to [RFC3986] for the specification of the URI format.
5959

6060
### `scheme`
6161

62-
The [scheme](https://datatracker.ietf.org/doc/html/rfc3986#section-3.1) **MUST** be `id.catalyst`;
62+
The [scheme](https://datatracker.ietf.org/doc/html/rfc3986#section-3.1) **MUST** be `id.catalyst`.
63+
64+
When used as a Catalyst ID, where only catalyst IDs would be used, the scheme can be omitted.
6365

6466
### `authority`
6567

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

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

@@ -100,21 +102,21 @@ capable of storing catalyst RBAC registration keychains.
100102
#### `authority` - `userinfo`
101103

102104
The [userinfo] is used to hold a user defined readable name that can be attached to the keychain.
103-
It may contain an optional `nonce` which is separated from the users name by a `:` and replaces a
105+
It may contain an optional `nonce` which is separated from the user's name by a `:` and replaces a
104106
traditional password used for HTTP basic authentication.
105107

106108
Because the name is not unique, and is provided by the user, it is informational only.
107109
A URI is identical, provided the hostname and path are the same, the [userinfo] does not play
108110
a part in validating or finding the catalyst keychain being referenced.
109111

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

113115
Applications which use the `nonce` will define its use, anything that does not use the `nonce` will ignore it.
114116

115117
##### Example `userinfo` with a `hostname`
116118

117-
* `anne@cardano` - username `anne` no nonce.
119+
* `anne@cardano` - username `anne` no nonce.
118120
* `blake:1737101079@midnight` - username `blake` with nonce 1737101079.
119121
* `:173710179#ethereum` - no username with nonce 173710179.
120122

@@ -157,36 +159,38 @@ The first implementation will be Catalyst Voices.
157159
* Role 0 - Rotation 0.
158160
* `username` - undefined.
159161
* `nonce` - undefined.
160-
In this example, it is exactly the same as the `<key>`.
162+
* In this example, it is identical to `<key>/0/0` or `<key>/0`.
161163
* `id.catalyst://cardano/<key>/0`
162164
* A Signing key registered on the Cardano Main network.
163165
* Role 0 - Rotation 0.
164166
* `username` - undefined.
165167
* `nonce` - undefined.
168+
* In this example, it is identical to `<key>/0/0` or `<key>`.
166169
* `id.catalyst://gary@cardano/<key>/0/0`
167170
* A Signing key registered on the Cardano Main network.
168171
* Role 0 - Rotation 0.
169172
* `username` - `gary`.
170173
* `nonce` - undefined.
174+
* In this example, it is identical to `<key>` or `<key>/0`.
171175
* `id.catalyst://faith@preprod@cardano/<key>/7/3`
172176
* A Signing key registered on the Cardano pre-production network.
173177
* Role 7 - Rotation 3.
174178
* `username` - `faith`
175179
* `nonce` - undefined.
176-
The Key for Role 7, and its third published rotation
180+
* The Key for Role 7, and its third published rotation
177181
(i.e., the fourth key published, the first is the initial key, plus 3 rotations following it).
178182
* `id.catalyst://faith:173710179@preprod@cardano/<key>/2/0#encrypt`
179183
* A Public Encryption key registered on the Cardano pre-production network.
180184
* Role 2 - Rotation 0.
181185
* `username` - `faith`
182186
* `nonce` - 173710179.
183-
The initially published Public Encryption Key for Role 2.
187+
* The initially published Public Encryption Key for Role 2.
184188
* `kid.catalyst-rbac://:173710179@midnight/<key>/0/1`
185189
* A Signing key registered on the Midnight Blockchain Main network
186190
* Role 0 - Rotation 1.
187191
* `username` - undefined.
188192
* `nonce` - 173710179.
189-
In this example, it is NOT the same as the `<key>`, as it identifies the first rotation after `<key>`.
193+
* In this example, it is NOT the same as the `<key>`, as it identifies the first rotation after `<key>`.
190194
* `kid.catalyst-rbac://midnight/<key>/2/1#encrypt`
191195
* A public encryption key registered on the Midnight Blockchain Main network.
192196
* Role 2 - Rotation 1.

rust/catalyst-types/Cargo.toml

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,9 +26,10 @@ num-traits = "0.2.19"
2626
orx-concurrent-vec = "3.1.0"
2727
pallas-crypto = { version = "0.30.1", git = "https://github.com/input-output-hk/catalyst-pallas.git", rev = "9b5183c8b90b90fe2cc319d986e933e9518957b3" }
2828
serde = { version = "1.0.217", features = ["derive"] }
29-
thiserror = "2.0.9"
29+
thiserror = "2.0.11"
3030
base64-url = "3.0.0"
31-
uuid = { version = "1.11.0", features = ["v4", "v7", "serde"] }
31+
uuid = { version = "1.12.0", features = ["v4", "v7", "serde"] }
32+
chrono = "0.4.39"
3233

3334
[dev-dependencies]
3435
ed25519-dalek = { version = "2.1.1", features = ["rand_core"] }

rust/catalyst-types/src/id_uri/errors.rs

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,15 @@ use super::{key_rotation::KeyRotationError, role_index::RoleIndexError};
77

88
/// Errors that can occur when parsing a `KidUri`
99
#[derive(Display, Error, Debug)]
10-
pub enum KidUriError {
10+
pub enum IdUriError {
1111
/// Invalid KID URI
12-
InvalidURI(#[from] fluent_uri::error::ParseError),
13-
/// Invalid Scheme, not a KID URI
12+
InvalidURI(#[from] fluent_uri::error::ParseError<String>),
13+
/// Invalid Scheme, not a ID URI
1414
InvalidScheme,
1515
/// Network not defined in URI
1616
NoDefinedNetwork,
17+
/// Invalid Nonce
18+
InvalidNonce,
1719
/// Path of URI is invalid
1820
InvalidPath,
1921
/// Role 0 Key in path is invalid

rust/catalyst-types/src/id_uri/key_rotation.rs

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,23 @@ pub enum KeyRotationError {
2121
#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
2222
pub struct KeyRotation(u16);
2323

24+
impl KeyRotation {
25+
/// Default Role Index
26+
pub const DEFAULT: KeyRotation = KeyRotation(0);
27+
28+
/// Is the `KeyRotation` the default value
29+
#[must_use]
30+
pub fn is_default(self) -> bool {
31+
self == Self::DEFAULT
32+
}
33+
}
34+
35+
impl Default for KeyRotation {
36+
fn default() -> Self {
37+
Self::DEFAULT
38+
}
39+
}
40+
2441
impl From<u16> for KeyRotation {
2542
fn from(value: u16) -> Self {
2643
Self(value)

0 commit comments

Comments
 (0)