---
title: SAIF.NetCore.SystemHash operations and processes
summary: Business and technical operations supported by this library.
status: draft
owner: SAIF Platform Team
last_reviewed: 2026-10-02
library: SAIF.NetCore.SystemHash
reference_type: package
---

# SAIF.NetCore.SystemHash operations and processes

This page is the operation catalog and cross-operation hub for this library. Each operation's detailed, step-by-step logic lives in its own page under `operations/`.

## Operation catalog
| Operation | Intent | Trigger | Inputs | Outputs | Rules |
| --- | --- | --- | --- | --- | --- |
| [Compute a salted system hash](operations/compute-salted-system-hash.md) | Issue a time-stamped, randomized identity credential for a named system. | Caller needs a credential for a `SystemType`/name pair; used directly, and internally by `Get`. | `type` (`SystemType`), `systemName` (string) | Salted hash string (~120 chars), regenerated and randomized per call | [BR-SH-01](business-rules.md#br-sh-01-identity-hash-encoding), [BR-SH-02](business-rules.md#br-sh-02-identity-string-uses-type-ordinal), [BR-SH-03](business-rules.md#br-sh-03-credential-embeds-creation-time), [BR-SH-04](business-rules.md#br-sh-04-credential-randomized-per-call) |
| [Compute an unsalted system hash on demand](operations/compute-unsalted-system-hash.md) | Produce the canonical identity hash a validator can compare against a de-salted credential. | Validating service needs the identity hash for comparison (external; no in-repo caller). | `type`, `systemName` | Deterministic 44-char Base64 SHA-256 string | [BR-SH-01](business-rules.md#br-sh-01-identity-hash-encoding), [BR-SH-02](business-rules.md#br-sh-02-identity-string-uses-type-ordinal), [BR-SH-05](business-rules.md#br-sh-05-immediate-hash-is-unsalted) |
| [Get the current application's system hash](operations/get-current-application-hash.md) | Resolve the calling application's own identity and issue a credential for it. | Application/library needs its own credential (e.g., for a secure-setting request). | `type` | Salted hash for `"{assemblyName}-{(int)type}"` | [BR-SH-06](business-rules.md#br-sh-06-system-name-from-assembly), [BR-SH-07](business-rules.md#br-sh-07-credential-is-not-cached) |
| [Resolve the identity assembly](operations/resolve-identity-assembly.md) | Determine which assembly's simple name identifies the current system. | Called internally by `Get`, or directly by a caller that wants to inspect the resolved assembly. | none (uses constructor-injected `_assembly` if present) | `Assembly` | [BR-SH-06](business-rules.md#br-sh-06-system-name-from-assembly) |
| [Compute the identity hash](operations/compute-identity-hash.md) | Produce the deterministic SHA-256/Base64 digest shared by both the salted and unsalted operations. | Called internally by `ComputeHash` and `ComputeHashNow`. | `type`, `systemName` | 44-char Base64 SHA-256 string | [BR-SH-01](business-rules.md#br-sh-01-identity-hash-encoding), [BR-SH-02](business-rules.md#br-sh-02-identity-string-uses-type-ordinal) |
| [De-salt and validate credential lifetime](operations/validate-credential-lifetime.md) | Recover the identity hash from a previously issued credential and reject it if expired or not yet valid. | Validating service receives a salted credential (external; exercised only by this library's unit tests in-repo). | `systemHashValue`, `expireSeconds`, `nowBufferSeconds` | Unsalted 44-char hash, or `SystemHashExpiredException` | [BR-SH-03](business-rules.md#br-sh-03-credential-embeds-creation-time), [BR-SH-08](business-rules.md#br-sh-08-credential-lifetime-window), [BR-SH-09](business-rules.md#br-sh-09-malformed-credential-raises-bcl-exceptions), [BR-SH-10](business-rules.md#br-sh-10-lifetime-validation-is-not-identity) |

## Process flow diagram
The following diagram visualizes the primary issue-and-validate round trip for a system-hash credential.
The simplified acceptance window shown below holds when `nowBufferSeconds` is any value other than `int.MinValue` and when `createDate.AddSeconds(expireSeconds)` stays within the representable `DateTime` range. If that date shift falls outside the `DateTime` range, `DateTime.AddSeconds` throws `ArgumentOutOfRangeException`, and the exception propagates uncaught rather than becoming `SystemHashExpiredException`. The `nowBufferSeconds * -1` negation never throws: the project does not enable overflow checking and the method uses no `checked` block, so integer arithmetic is unchecked. At `int.MinValue` the negation wraps silently back to `int.MinValue`. Both bound checks then shift `now` back by about 68 years. The method does not special-case this value in code, but because both arms of the window check then collapse onto the same shifted value, the diagram shows it as its own comparison, `shiftedNow = now.AddSeconds(int.MinValue); shiftedNow >= createDate && shiftedNow < expires`, rather than the simplified symmetric window used for every other `nowBufferSeconds`. A current credential still fails that shifted window and is rejected with `SystemHashExpiredException`, but a credential with a `createDate` roughly 68+ years in the past, combined with a sufficiently large `expireSeconds`, can satisfy the shifted window and be accepted instead. See [De-salt and validate credential lifetime](operations/validate-credential-lifetime.md) for the literal evaluation order.

```mermaid
flowchart TD
	Start([Caller needs a credential]) --> ResolveAssembly[Resolve identity assembly]
	ResolveAssembly --> ComputeIdentity["Compute identity hash: SHA-256/Base64 of systemName-ordinal"]
	ComputeIdentity --> Salt[Salt with SaltShaker DateTime.Now]
	Salt --> Issue(["Return salted credential ~120 chars"])
	Issue --> Present[Caller presents credential to external validator]
	Present --> Desalt["De-salt: SaltShaker.BlandHash recovers createDate"]
	Desalt --> Malformed{Well-formed HashUtil format?}
	Malformed -->|No| BclError(["BCL exception: ArgumentOutOfRangeException /<br>FormatException / NullReferenceException"])
	Malformed -->|Yes| Domain{"createDate + expireSeconds<br>within DateTime range?"}
	Domain -->|No| ArithError(["Uncaught ArgumentOutOfRangeException<br>from DateTime.AddSeconds"])
	Domain -->|Yes| MinVal{"nowBufferSeconds<br>== int.MinValue?"}
	MinVal -->|Yes, wraps to int.MinValue| MinValWindow{"shiftedNow = now.AddSeconds(int.MinValue);<br>shiftedNow >= createDate && shiftedNow < expires?"}
	MinVal -->|No| Window{"createDate within<br>(now − abs(buffer) − expireSeconds, now + abs(buffer)]?"}
	Window -->|No| Expired([Throw SystemHashExpiredException])
	Window -->|Yes| ReturnHash[Return unsalted hash]
	MinValWindow -->|Yes| ReturnHash
	MinValWindow -->|No| Expired
	ReturnHash --> Compare{Validator compares against authorized/ComputeHashNow hash}
	Compare -->|Match| Authorized([Credential accepted])
	Compare -->|No match| Rejected([Credential rejected])
```

## Failure and edge-case behavior
- A malformed or tampered credential causes `SaltShaker.BlandHash` to raise `ArgumentOutOfRangeException`, `FormatException`, or `NullReferenceException` — not `SystemHashExpiredException` — because `RemoveSystemHashSaltAndValidateLifetime` does not wrap the de-salt call in a try/catch ([BR-SH-09](business-rules.md#br-sh-09-malformed-credential-raises-bcl-exceptions)).
- A `SystemType` ordinal change in `SAIF.NetCore.ServiceContracts` silently changes the identity hash for every affected system type without any error at either the issuing or validating side ([BR-SH-02](business-rules.md#br-sh-02-identity-string-uses-type-ordinal)).
- Calling `Get()` or `new SystemHashService()` without an injected assembly most likely resolves the identity to the `SAIF.NetCore.SystemHash` assembly itself rather than the consuming application, since `GetAssembly()`'s caller is `Get` itself — unless the JIT inlines the call.*
- `RemoveSystemHashSaltAndValidateLifetime` never establishes identity on its own; a validator that does not independently compare the returned hash against an authorized value accepts any fresh, well-formed credential ([BR-SH-10](business-rules.md#br-sh-10-lifetime-validation-is-not-identity)).
- There are no in-repo production callers of `ComputeHashNow` or `RemoveSystemHashSaltAndValidateLifetime`; both are intended for the external Environment API / CryptoAPI validating service.*

## Related documentation
- [Index](index.md)
- [Overview](overview.md)
- [Architecture](architecture.md)
- [Dependencies](dependencies.md)
- [Business rules](business-rules.md)
- [Security and authorization](security-authorization.md)
- [API reference](api/index.md)

> **Note:** Statements marked with `*` were inferred from code structure, naming
> conventions, or contextual evidence where direct confirmation was not available
> in source artifacts.

## Sources
- `src/SAIF.NetCore.SystemHash/SAIF.NetCore.SystemHash/SAIF.NetCore.SystemHash/SystemHashService.cs`
- `src/SAIF.NetCore.SystemHash/SAIF.NetCore.SystemHash/SAIF.NetCore.SystemHash.Tests/SystemHashTests.cs`
