Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
fd5fe2b
define new event wit for auth
bkioshn Oct 22, 2025
7d6caba
setup auth module
bkioshn Oct 22, 2025
5d1719c
fix integration test
bkioshn Oct 22, 2025
e27f36c
add auth level
bkioshn Oct 24, 2025
8310fda
implement auth
bkioshn Oct 24, 2025
06d46d2
fix typo
bkioshn Oct 24, 2025
75466d3
Merge branch 'main' into feat/auth-token
bkioshn Oct 24, 2025
4074d8f
fix integration test
bkioshn Oct 24, 2025
d0003ef
remove auth module
bkioshn Oct 24, 2025
c9d2edd
revert
bkioshn Oct 24, 2025
e78bf21
setup auth module
bkioshn Oct 24, 2025
857b2b1
copy rbac related
bkioshn Oct 24, 2025
9ef92e7
add auth mod to just
bkioshn Oct 24, 2025
92e9063
impl auth module
bkioshn Oct 24, 2025
d8b2be3
Merge branch 'main' into feat/auth-token
bkioshn Oct 24, 2025
d22d1f9
typo
bkioshn Oct 24, 2025
1ead360
Merge branch 'feat/auth-token' into feat/auth-mod
bkioshn Oct 24, 2025
e49f4ce
fix cspell
bkioshn Oct 24, 2025
324ab51
cleanup
bkioshn Oct 24, 2025
0ea14d8
cspell
bkioshn Oct 24, 2025
395f070
typo
bkioshn Oct 25, 2025
d7d9488
Merge branch 'main' into feat/auth-token
stevenj Oct 28, 2025
465f645
Merge branch 'feat/auth-token' into feat/auth-mod
stevenj Oct 28, 2025
3451175
Merge branch 'main' into feat/auth-token
cong-or Nov 4, 2025
bbe3a45
Merge branch 'feat/auth-token' into feat/auth-mod
cong-or Nov 4, 2025
59c4f13
Merge branch 'main' into feat/auth-mod
cong-or Nov 4, 2025
bf2f460
Merge branch 'main' into feat/auth-mod
cong-or Nov 5, 2025
377fb9b
Merge branch 'main' into feat/auth-mod
cong-or Nov 7, 2025
b889266
fix format
bkioshn Nov 10, 2025
05242cf
Merge branch 'main' into feat/auth-mod
bkioshn Nov 10, 2025
1dad69f
update deps
bkioshn Nov 10, 2025
15de06a
chore: fix miscellaneous
bkioshn Nov 10, 2025
2e5a92b
fix linter
bkioshn Nov 11, 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
1 change: 1 addition & 0 deletions .config/dictionaries/project.dic
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,7 @@ rfind
Rmax
Rmin
rngs
rsplit
rollouts
rusqlite
rustc
Expand Down
53 changes: 53 additions & 0 deletions hermes/apps/athena/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

58 changes: 31 additions & 27 deletions hermes/apps/athena/manifest_app.json
Original file line number Diff line number Diff line change
@@ -1,29 +1,33 @@
{
"$schema": "https://raw.githubusercontent.com/input-output-hk/hermes/main/hermes/schemas/hermes_app_manifest.schema.json",
"name": "athena",
"icon": "icon.svg",
"metadata": "metadata.json",
"modules": [
{
"package": "modules/http-proxy/lib/http_proxy.hmod",
"name": "http_proxy"
},
{
"package": "modules/rbac-registration-indexer/lib/rbac_registration_indexer.hmod",
"name": "rbac_registration_indexer"
},
{
"package": "modules/rbac-registration/lib/rbac_registration.hmod",
"name": "rbac_registration"
},
{
"package": "modules/staked-ada-indexer/lib/staked_ada_indexer.hmod",
"name": "staked_ada_indexer"
},
{
"package": "modules/staked-ada/lib/staked_ada.hmod",
"name": "staked_ada"
}
],
"www": "modules/http-proxy/lib/www"
"$schema": "https://raw.githubusercontent.com/input-output-hk/hermes/main/hermes/schemas/hermes_app_manifest.schema.json",
"name": "athena",
"icon": "icon.svg",
"metadata": "metadata.json",
"modules": [
{
"package": "modules/http-proxy/lib/http_proxy.hmod",
"name": "http_proxy"
},
{
"package": "modules/rbac-registration-indexer/lib/rbac_registration_indexer.hmod",
"name": "rbac_registration_indexer"
},
{
"package": "modules/rbac-registration/lib/rbac_registration.hmod",
"name": "rbac_registration"
},
{
"package": "modules/staked-ada-indexer/lib/staked_ada_indexer.hmod",
"name": "staked_ada_indexer"
},
{
"package": "modules/staked-ada/lib/staked_ada.hmod",
"name": "staked_ada"
},
{
"package": "modules/auth/lib/auth.hmod",
"name": "auth"
}
],
"www": "modules/http-proxy/lib/www"
}
30 changes: 30 additions & 0 deletions hermes/apps/athena/modules/auth/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
[package]
edition.workspace = true
name = "auth"
version = "0.1.0"
license = "MIT OR Apache-2.0"

[lints]
workspace = true

[lib]
crate-type = ["cdylib"]

[dependencies]
shared = { version = "0.1.0", path = "../../shared", features = ["cardano-blockchain-types"] }
anyhow = "1.0.98"
ed25519-dalek = "2.1.1"
base64 = "0.22.1"
chrono = "0.4.38"
regex = "1.11.1"
thiserror = "1.0.68"
rand = "0.8.5"
serde_json = "1.0.142"
serde = "1.0.226"

cardano-blockchain-types = { version = "0.0.8", git = "https://github.com/input-output-hk/catalyst-libs", tag = "cardano-blockchain-types/v0.0.8" }
rbac-registration = { version = "0.0.14", git = "https://github.com/input-output-hk/catalyst-libs.git", tag = "rbac-registration/v0.0.14" }
catalyst-types = { version = "0.0.10", git = "https://github.com/input-output-hk/catalyst-libs.git", tag = "catalyst-types/v0.0.10" }

[dev-dependencies]
test-case = "3.3.1"
22 changes: 22 additions & 0 deletions hermes/apps/athena/modules/auth/Earthfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
VERSION 0.8

IMPORT ../../../../ AS hermes
IMPORT ../.. AS athena

build-auth:
DO athena+BUILD_ATHENA_COMPONENT --out=auth.wasm

local-build-auth:
FROM scratch
COPY +build-auth/auth.wasm .
SAVE ARTIFACT auth.wasm AS LOCAL lib/auth.wasm


auth-package-module:
FROM hermes+build

COPY lib/ .
COPY +build-auth/auth.wasm .

RUN ./target/release/hermes module package manifest_module.json
SAVE ARTIFACT auth.hmod
Empty file.
1 change: 1 addition & 0 deletions hermes/apps/athena/modules/auth/lib/config.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{}
1 change: 1 addition & 0 deletions hermes/apps/athena/modules/auth/lib/config.schema.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{}
13 changes: 13 additions & 0 deletions hermes/apps/athena/modules/auth/lib/manifest_module.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{
"$schema": "https://raw.githubusercontent.com/input-output-hk/hermes/main/hermes/schemas/hermes_module_manifest.schema.json",
"name": "auth",
"metadata": "metadata.json",
"component": "auth.wasm",
"config": {
"file": "config.json",
"schema": "config.schema.json"
},
"settings": {
"schema": "settings.schema.json"
}
}
26 changes: 26 additions & 0 deletions hermes/apps/athena/modules/auth/lib/metadata.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
{
"$schema": "https://raw.githubusercontent.com/input-output-hk/hermes/main/hermes/schemas/hermes_app_metadata.schema.json",
"name": "Authentication and Authorization service",
"version": "V0.1.0",
"description": "Catalyst authentication and authorization service",
"src": [
"https://github.com/input-output-hk/hermes",
"https://github.com/input-output-hk/catalyst-voices"
],
"copyright": ["Copyright Ⓒ 2024, IOG Singapore."],
"license": [
{
"spdx": "Apache-2.0",
"file": "/srv/data/apache2.txt"
},
{
"spdx": "MIT",
"file": "/srv/data/mit.txt"
}
],
"developer": {
"name": "IOG Singapore",
"contact": "[email protected]",
"payment": "wallet address"
}
}
1 change: 1 addition & 0 deletions hermes/apps/athena/modules/auth/lib/settings.schema.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{}
33 changes: 33 additions & 0 deletions hermes/apps/athena/modules/auth/src/api_keys.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
//! API Key auth scheme is used ONLY by internal endpoints.
//!
//! Its purpose is to prevent their use externally, if they were accidentally exposed.
//!
//! It is NOT to be used on any endpoint intended to be publicly facing.

use std::env;

use anyhow::{bail, Result};

use crate::{extract_header, hermes::http_gateway::api::Headers};

/// The header name that holds the API Key
pub(crate) const API_KEY_HEADER: &str = "X-API-Key";

/// Check if the API Key is correctly set.
pub(crate) fn check_api_key(headers: &Headers) -> Result<()> {
if let Some(key) = extract_header!(headers, API_KEY_HEADER) {
if check_internal_api_key(&key) {
return Ok(());
}
}
bail!("Invalid API Key");
}

/// Check a given key matches the internal API Key
fn check_internal_api_key(value: &str) -> bool {
// TODO: This should be moved to application setting/config
match env::var("INTERNAL_API_KEY") {
Ok(expected_key) => value == expected_key,
Err(_) => false,
}
}
10 changes: 10 additions & 0 deletions hermes/apps/athena/modules/auth/src/database/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
//! Database access layer for RBAC registration.
// TODO - This is redundant to what is in rbac-registration module, need to move the share

pub(crate) mod query_builder;
pub(crate) mod select;

/// RBAC registration persistent table name.
pub(crate) const RBAC_REGISTRATION_PERSISTENT_TABLE_NAME: &str = "rbac_registration_persistent";
/// RBAC registration volatile table name.
pub(crate) const RBAC_REGISTRATION_VOLATILE_TABLE_NAME: &str = "rbac_registration_volatile";
41 changes: 41 additions & 0 deletions hermes/apps/athena/modules/auth/src/database/query_builder.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
//! `SQLite` query builders

/// Query builder
pub(crate) struct QueryBuilder;

impl QueryBuilder {
/// Select a root registration from a catalyst ID.
/// The earliest (lowest `slot_no`, then lowest `txn_idx`) registration
/// is considered the canonical/valid registration if multiple exist.
pub(crate) fn select_root_reg_by_cat_id(table: &str) -> String {
format!(
r"
SELECT txn_id, slot_no, txn_idx
FROM {table}
WHERE prv_txn_id IS NULL
AND problem_report IS NULL
AND catalyst_id = ?
ORDER BY slot_no ASC, txn_idx ASC
LIMIT 1;
"
)
}

/// Select a child registration from a parent registration
/// The earliest (lowest `slot_no`, then lowest `txn_idx`) registration
/// is considered the canonical/valid registration if multiple exist.
///
/// The child is linked to the parent by the `prv_txn_id` field.
pub(crate) fn select_child_reg_from_parent(table: &str) -> String {
format!(
r"
SELECT txn_id, slot_no, txn_idx
FROM {table}
WHERE prv_txn_id = ?
AND problem_report IS NULL
ORDER BY slot_no ASC, txn_idx ASC
LIMIT 1;
"
)
}
}
Loading
Loading