Kory Draughn, Chief Technologist

Martin Flores, Software Developer

iRODS Consortium

iRODS HTTP API v0.5.0

June 17-20, 2025

iRODS User Group Meeting 2025

Durham, NC

Rebalance - Pre 5.1.0

  • Rebalance halts on first issue
    • Data objects after halt not replicated
      • Even if replication was possible
  • Large amounts of manual intervention possibly required
$ iadmin modresc thingToRebalance rebalance
remote addresses: 172.19.0.3 ERROR: rcGeneralAdmin failed with error -808000 CAT_NO_ROWS_FOUND

Rebalance - 5.1.0

  • Rebalance persists after issue
    •  All possible replications will be done
  • New error to notify user
    • REBALANCE_NOT_COMPLETE
  • Additional comands in docs to query data objects requiring intervention
$ iadmin modresc thingToRebalance rebalance
remote addresses: 172.19.0.3 ERROR: rcGeneralAdmin failed with error -1834000 REBALANCE_NOT_COMPLETE

$ iquest "SELECT COLL_NAME, DATA_NAME WHERE DATA_RESC_HIER LIKE 'thingToRebalance;%' and DATA_REPL_STATUS != '1'"
COLL_NAME = /tempZone/home/alice/dataHere
DATA_NAME = foo1
------------------------------------------------------------
COLL_NAME = /tempZone/home/alice/dataHere
DATA_NAME = foo3
------------------------------------------------------------
COLL_NAME = /tempZone/home/alice/dataHere
DATA_NAME = foo5
------------------------------------------------------------

$ iquest "SELECT COUNT(DATA_ID) WHERE DATA_RESC_HIER LIKE 'thingToRebalance;%' and DATA_REPL_STATUS != '1'"
DATA_ID = 6

Policy Composition - Overview

Policy Composition - Example Configuration

{
    "instance_name": "irods_rule_engine_plugin-event_handler-data_object_modified-instance",
    "plugin_name": "irods_rule_engine_plugin-event_handler-data_object_modified",
    "plugin_specific_configuration": {
        "policies_to_invoke": [
            {
                "active_policy_clauses": [
                    "post"
                ],
                "events": [
                    "put",
                    "create",
                    "write",
                    "registration"
                ],
                "policy_to_invoke": "irods_policy_data_replication",
                "configuration": {
                    "destination_resource": "AnotherResc"
                }
            }
        ]
    }
}

Policy Composition - Release and Previous Presentations

User Mapping - Overview

  • Abstracted Mapping of JWTs to iRODS users
  • Previously built-in mapping now plugins
    • user_attribute_mapping -> libirods_http_api_plugin-local_file.so
    • irods_user_claim -> libirods_http_api_plugin-user_claim.so
  • Flexible mapping
    • e.g. query an external service for the mappings

User Mapping - Overview

User Mapping - Plugin Interface

  • Simple C interface
  • Full documentation in interface.h
/// Initializes the user mapping plugin.
int user_mapper_init(const char* _args);

/// Matches the given information to a user.
int user_mapper_match(const char* _param, char** _match);

/// Frees a C-string generated from the user mapping plugin.
void user_mapper_free(char* _data);

/// Executes clean-up for the user mapping plugin.
int user_mapper_close();

User Mapping - Local File Configuration Example

...
// Defines relevant information related to the User Mapping plugin system.
// Allows for the selection and configuration of the plugin.
"user_mapping": {
  // The full path to the desired plugin to load.
  "plugin_path": "/some/path/libirods_http_api_plugin-local_file.so",

  // The configuration information required by
  // the selected plugin to execute properly.
  "configuration": {
    "file_path": "/some-file.json"
  }
}
...
...
"user_attribute_mapping": {
  "rodsBob": {
    "email": "bob@bobtopia.example",
    "sub": "a.very.real.sub",
    "phone_number": "56709"
  },
  "rodsAlice": {
    "email": "al-1s@wonderland.example",
    "sub": "a.different.sub"
  }
}
...

Old Configuration

New Configuration

User Mapping - Local File Configuration Example

Text

{
    "rodsAlice": {
        "email": "alice@example.org",
        "sub": "123-abc-456-xyz"
    },
    "rodsBob": {
        "email": "bob@example.org",
        "phone": "56709"
    }
}

Local File Mapping Example

User Mapping User Claim Configuration Example

...
"user_mapping": {
  "plugin_path": "/some/path/libirods_http_api_plugin-user_claim.so",

  "configuration": {
    "irods_user_claim": "irods_username"
  }
}
...
...
"irods_user_claim": "irods_username"
...

Old Configuration

New Configuration

Local JWT Access Token Validation

Local JWT Access Token Validation

  • Validate Tokens locally using JWKs
  • Similar to access token introspection
  • Retrieve JWKs on first validation attempt
    • Minimal communication to OpenID Provider
  • Support for more OpenID Providers

Local JWT Access Token Validation - Supported Algorithms

Table in Section 3.1 from JWA RFC 7518

Local JWT Access Token Validation - Nonstandard Behavior

  • Some OpenID providers may not use client_secret for symmetric ID Tokens
    • Allow for non-standard client secrets (nonstandard_id_token_secret)
  • JWT Profile for OAuth 2.0 Access Tokens (RFC 9068)
    • Allow for "jwt" vs strictly "at+jwt" in "typ" header

HTTP API as an OAuth 2.0 Protected Resource

Example of Protected Resource Communications

HTTP API Local Validation 

Example of Local Validation

HTTP API Local Validation 

Demo

Future Improvements

  • Encrypted JWTs
    • Depends on jwt-cpp library
  • Fix timeout issue on some Providers
  • Depend on OAuth 2.0 specs only
    • If enough providers support RFC 8414
  • Allow configurable Access Token inspection
  • Remove Client Mode
  • Re-retrieve JWKs when possibly out of date
  • Community suggestions

References

References

Thank you!

Questions?

Copy of UGM 2025 - iRODS HTTP API v0.5.0

By Martin Flores Jr

Copy of UGM 2025 - iRODS HTTP API v0.5.0

  • 226