> For the complete documentation index, see [llms.txt](https://docs.talus.network/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.talus.network/talus-docs-v2.1.0/reference/sdk/actions-network-auth.md).

# Network Authentication Actions

**Audience:** Nexus SDK integrators (Rust).

**Area:** Network authentication actions.

**Generated from:** Nexus SDK network-auth API at release `v2.1.0` commit `45d397aafcfbeeeaf5032d5fb9fa5d99b3f36205`; the generated inventory is preserved and 2.1.0 client helpers are source-verified.

`NexusClient::network_auth` provides the action facade, and `NetworkAuthReader` is its read-only counterpart. An on-chain Tool key has an ID, but signed-HTTP v3 sends no Tool KID header: request headers use signature version, leader ID, leader key ID, input hash, leader signature, and nonce; response headers use signature version and Tool signature.

### Client and ownership boundary

`NetworkAuthActions::from_client` derives the network-auth action facade from the configured client. Tool owner capability, ToolCashier administration, and network-auth key/allowlist records answer different authorization questions; preserve the exact capability and object IDs returned by the registration transaction. Signed HTTP v3 carries leader/key and signature metadata, while a Tool KID is not added as a request header.

### Source-derived public API inventory

#### `RegisteredToolKey`

```rust
pub struct RegisteredToolKey {
    /// Transaction digest that performed the registration.
    pub tx_digest: sui::types::Digest,
    /// Stable on chain [`ToolAnchor`] object ID.
    pub tool_id: sui::types::Address,
    /// Registered on-chain key ID; signed-HTTP v3 does not carry it in a header.
    pub tool_kid: u64,
    /// Registered Ed25519 public key bytes.
    pub public_key: [u8; 32],
    /// Deterministic [`KeyBinding`] object ID below [`NetworkAuth`].
    pub binding_object_id: sui::types::Address,
}
```

#### `ToolKeyEntry`

```rust
pub struct ToolKeyEntry {
    /// On-chain key identifier; signed-HTTP v3 does not carry it in a header.
    pub kid: u64,
    /// Hex encoded Ed25519 public key.
    pub public_key_hex: String,
    /// Millisecond timestamp when the key was added.
    pub added_at_ms: u64,
    /// Whether the key has been revoked.
    pub revoked: bool,
}
```

#### `ToolKeyList`

```rust
pub struct ToolKeyList {
    /// On chain object ID of the [`KeyBinding`] for this tool.
    pub binding_object_id: sui::types::Address,
    /// The currently active key ID, if any.
    pub active_key_id: Option<u64>,
    /// The next key ID that will be assigned on the next registration.
    pub next_key_id: u64,
    /// All key entries, sorted by kid ascending.
    pub keys: Vec<ToolKeyEntry>,
}
```

#### `ActiveEd25519Key`

```rust
pub struct ActiveEd25519Key {
    /// Key identifier used by signed HTTP messages.
    pub kid: u64,
    /// Exact Ed25519 public key bytes.
    pub public_key: [u8; 32],
}
```

#### `ResolvedKeyBinding`

```rust
pub struct ResolvedKeyBinding {
    /// Current supported binding state.
    pub binding: Response<KeyBindingInnerV1>,
    /// Active supported Ed25519 key, when configured.
    pub active_key: Option<ActiveEd25519Key>,
}
```

#### `NetworkAuthActions`

```rust
pub struct NetworkAuthActions {
    pub(super) client: NexusClient,
}
```

#### `NetworkAuthActions::binding_object_id`

```rust
pub async fn binding_object_id(
        &self,
        identity: &IdentityKey,
    ) -> Result<sui::types::Address, NexusError> {
```

#### `NetworkAuthActions::register_tool_message_key`

```rust
pub async fn register_tool_message_key(
        &self,
        tool_fqn: ToolFqn,
        owner_cap_over_tool: sui::types::Address,
        tool_signing_key: SigningKey,
        description: Option<Vec<u8>>,
    ) -> Result<RegisteredToolKey, NexusError> {
```

#### `NetworkAuthActions::list_tool_keys`

```rust
pub async fn list_tool_keys(
        &self,
        tool_fqn: &ToolFqn,
    ) -> Result<Option<ToolKeyList>, NexusError> {
```

#### `NetworkAuthActions::export_allowed_leaders_file_v1`

```rust
pub async fn export_allowed_leaders_file_v1(
        &self,
        leader_cap_ids: &[sui::types::Address],
    ) -> Result<AllowedLeadersFileV1, NexusError> {
```

#### `NetworkAuthActions::list_leader_cap_ids_from_network_auth`

```rust
pub async fn list_leader_cap_ids_from_network_auth(
        &self,
    ) -> Result<Vec<sui::types::Address>, NexusError> {
```

#### `NetworkAuthActions::export_allowed_leaders_file_v1_for_all_leaders`

```rust
pub async fn export_allowed_leaders_file_v1_for_all_leaders(
        &self,
    ) -> Result<AllowedLeadersFileV1, NexusError> {
```

#### `NetworkAuthReader`

```rust
pub struct NetworkAuthReader {
    crawler: Crawler,
    state_resolver: StateResolver,
    registry_type_origin_pkg_id: sui::types::Address,
    network_auth_object_id: sui::types::Address,
}
```

#### `NetworkAuthReader::new`

```rust
pub fn new(
        crawler: Crawler,
        registry_type_origin_pkg_id: sui::types::Address,
        network_auth_object_id: sui::types::Address,
    ) -> Self {
```

#### `from_client`

```rust
pub fn from_client(
        client: &NexusClient,
        registry_type_origin_pkg_id: sui::types::Address,
        network_auth_object_id: sui::types::Address,
    ) -> Self {
```

#### `from_rpc_url`

```rust
pub fn from_rpc_url(
        rpc_url: &str,
        registry_type_origin_pkg_id: sui::types::Address,
        network_auth_object_id: sui::types::Address,
    ) -> Result<Self, NexusError> {
```

#### `NetworkAuthReader::binding_object_id`

```rust
pub fn binding_object_id(
        &self,
        identity: &IdentityKey,
    ) -> Result<sui::types::Address, NexusError> {
```

#### `NetworkAuthReader::try_get_key_binding`

```rust
pub async fn try_get_key_binding(
        &self,
        identity: &IdentityKey,
    ) -> Result<Option<Response<KeyBindingInnerV1>>, NexusError> {
```

#### `NetworkAuthReader::try_get_active_key_binding`

```rust
pub async fn try_get_active_key_binding(
        &self,
        identity: &IdentityKey,
    ) -> Result<Option<ResolvedKeyBinding>, NexusError> {
```

#### `NetworkAuthReader::list_leader_cap_ids_from_network_auth`

```rust
pub async fn list_leader_cap_ids_from_network_auth(
        &self,
    ) -> Result<Vec<sui::types::Address>, NexusError> {
```

#### `NetworkAuthReader::export_allowed_leaders_file_v1_for_all_leaders`

```rust
pub async fn export_allowed_leaders_file_v1_for_all_leaders(
        &self,
    ) -> Result<AllowedLeadersFileV1, NexusError> {
```

#### `initial_tool_registration`

```rust
pub fn initial_tool_registration(
    tool_registry_id: sui::types::Address,
    meta: ToolMeta,
    signing_key: &SigningKey,
    invocation_cost_mist: u64,
) -> Result<OffChainToolRegistration, NexusError> {
```

#### `SignedHttpError`

```rust
pub enum SignedHttpError {
    #[error("unsupported signature version '{0}', expected '{SIGNATURE_VERSION_V3}'")]
    UnsupportedVersion(String),
    #[error("missing required header '{0}'")]
    MissingHeader(&'static str),
    #[error("invalid integer in header '{header}': {value}")]
    InvalidInteger { header: &'static str, value: String },
    #[error("invalid base64url in header '{header}': {source}")]
    InvalidBase64 {
        header: &'static str,
        #[source]
        source: base64::DecodeError,
    },
    #[error("invalid byte length in header '{header}': got {actual}, expected {expected}")]
    InvalidLength {
        header: &'static str,
        actual: usize,
        expected: usize,
    },
    #[error("unknown leader key (leader_id={leader_id}, leader_key_id={leader_key_id})")]
    UnknownLeaderKey {
        leader_id: String,
        leader_key_id: u64,
    },
    #[error("invalid ed25519 public key for {identity}")]
    InvalidPublicKey { identity: String },
    #[error("invalid ed25519 signature")]
    InvalidSignature,
    #[error("invalid allowed-leaders file: {0}")]
    InvalidAllowedLeadersFile(String),
    #[error("io error: {0}")]
    Io(#[from] std::io::Error),
}
```

#### `HEADER_SIGNATURE_VERSION`

```rust
pub const HEADER_SIGNATURE_VERSION: &str = "X-Nexus-Sig-V";
```

#### `HEADER_LEADER_ID`

```rust
pub const HEADER_LEADER_ID: &str = "X-Nexus-Leader-Id";
```

#### `HEADER_LEADER_KEY_ID`

```rust
pub const HEADER_LEADER_KEY_ID: &str = "X-Nexus-Leader-Key-Id";
```

#### `HEADER_INPUT_HASH`

```rust
pub const HEADER_INPUT_HASH: &str = "X-Nexus-Input-Hash";
```

#### `HEADER_LEADER_SIGNATURE`

```rust
pub const HEADER_LEADER_SIGNATURE: &str = "X-Nexus-Leader-Signature";
```

#### `HEADER_NONCE`

```rust
pub const HEADER_NONCE: &str = "X-Nexus-Nonce";
```

#### `HEADER_TOOL_SIGNATURE`

```rust
pub const HEADER_TOOL_SIGNATURE: &str = "X-Nexus-Tool-Signature";
```

#### `SIGNATURE_VERSION_V3`

```rust
pub const SIGNATURE_VERSION_V3: &str = "3";
```

#### `CANONICAL_TOOL_RESPONSE_CONTENT_TYPE`

```rust
pub const CANONICAL_TOOL_RESPONSE_CONTENT_TYPE: &str =
    "application/vnd.nexus.canonical-tool-response+bcs";
```

#### `EncodedRequestHeaders`

```rust
pub struct EncodedRequestHeaders {
    pub leader_id: String,
    pub leader_key_id: u64,
    pub input_hash: String,
    pub leader_signature: String,
    pub nonce: String,
}
```

#### `EncodedRequestHeaders::to_pairs`

```rust
pub fn to_pairs(&self) -> Vec<(&'static str, String)> {
```

#### `EncodedResponseHeaders`

```rust
pub struct EncodedResponseHeaders {
    pub tool_signature: String,
}
```

#### `EncodedResponseHeaders::to_pairs`

```rust
pub fn to_pairs(&self) -> Vec<(&'static str, String)> {
```

#### `RequestHeadersRef`

```rust
pub struct RequestHeadersRef<'a> {
    pub signature_version: Option<&'a str>,
    pub leader_id: Option<&'a str>,
    pub leader_key_id: Option<&'a str>,
    pub input_hash: Option<&'a str>,
    pub leader_signature: Option<&'a str>,
    pub nonce: Option<&'a str>,
}
```

#### `RequestHeadersRef::from_getter`

```rust
pub fn from_getter(mut get: impl FnMut(&str) -> Option<&'a str>) -> Self {
```

#### `ResponseHeadersRef`

```rust
pub struct ResponseHeadersRef<'a> {
    pub signature_version: Option<&'a str>,
    pub tool_signature: Option<&'a str>,
}
```

#### `ResponseHeadersRef::from_getter`

```rust
pub fn from_getter(mut get: impl FnMut(&str) -> Option<&'a str>) -> Self {
```

#### `AuthenticatedRequest`

```rust
pub struct AuthenticatedRequest {
    pub leader_id: String,
    pub leader_key_id: u64,
    pub input_hash: [u8; SHA256_LEN],
    pub leader_signature: [u8; ED25519_SIGNATURE_LEN],
    pub nonce: [u8; SHA256_LEN],
}
```

#### `LeaderKeyResolver`

```rust
pub trait LeaderKeyResolver: Send + Sync {
    fn leader_public_key(&self, leader_id: &str, leader_key_id: u64) -> Option<[u8; 32]>;
}
```

#### `sign_request`

```rust
pub fn sign_request(
    leader_id: impl Into<String>,
    leader_key_id: u64,
    input_hash: [u8; SHA256_LEN],
```

#### `authenticate_request`

```rust
pub fn authenticate_request(
    headers: RequestHeadersRef<'_>,
    keys: &dyn LeaderKeyResolver,
) -> Result<AuthenticatedRequest, SignedHttpError> {
```

#### `sign_response`

```rust
pub fn sign_response(
    leader_signature: &[u8; ED25519_SIGNATURE_LEN],
```

#### `verify_response`

```rust
pub fn verify_response(
    headers: ResponseHeadersRef<'_>,
    leader_signature: &[u8; ED25519_SIGNATURE_LEN],
```

#### `tool_signature_message`

```rust
pub fn tool_signature_message(
    leader_signature: &[u8; ED25519_SIGNATURE_LEN],
```

#### `sha256`

```rust
pub fn sha256(bytes: &[u8]) -> [u8; SHA256_LEN] {
```

#### `AllowedLeaders`

```rust
pub struct AllowedLeaders {
    keys: HashMap<(String, u64), [u8; 32]>,
    source_path: Option<PathBuf>,
}
```

#### `AllowedLeaders::from_path`

```rust
pub fn from_path(path: impl AsRef<Path>) -> Result<Self, SignedHttpError> {
```

#### `AllowedLeaders::source_path`

```rust
pub fn source_path(&self) -> Option<&Path> {
```

#### `AllowedLeadersFileV1`

```rust
pub struct AllowedLeadersFileV1 {
    pub version: u8,
    pub leaders: Vec<AllowedLeaderFileV1>,
}
```

#### `AllowedLeaderFileV1`

```rust
pub struct AllowedLeaderFileV1 {
    pub leader_id: String,
    pub keys: Vec<AllowedLeaderKeyFileV1>,
}
```

#### `AllowedLeaderKeyFileV1`

```rust
pub struct AllowedLeaderKeyFileV1 {
    pub kid: u64,
    pub public_key: String,
}
```


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the following URL with the `ask` and `goal` query parameters:

```
GET https://docs.talus.network/talus-docs-v2.1.0/reference/sdk/actions-network-auth.md?ask=<question>&goal=<user_goal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is what the user is ultimately trying to achieve, the reason they need the answer. Sharing it helps GitBook give you a better, more relevant answer. A goal is most helpful when it describes the outcome the user wants rather than restating the question. For example, with `ask=how do I create an API token`, a goal like `build a script that syncs our docs to a CMS` lets GitBook tailor the answer to that use case.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
