---
title: Construct OIDC application credentials
summary: Parse a decrypted raw credential string into a `ClientId`/`ClientSecret` pair.
status: draft
owner: Framework.NCore maintainers
last_reviewed: 2026-10-02
library: SAIF.NetCore.ServiceContracts
reference_type: package
operation_id: OP-01
trigger: A consumer constructs `OidcAppCredentials` from a raw string decrypted from CryptoApi.
---

# Construct OIDC application credentials

Parse a decrypted raw credential string into a `ClientId`/`ClientSecret` pair. This operation is triggered when a consumer constructs `OidcAppCredentials` from a raw string decrypted from CryptoApi.

| Field | Value |
| --- | --- |
| **Operation ID** | OP-01 |
| **Trigger** | A consumer constructs `OidcAppCredentials` from a raw string decrypted from CryptoApi. |
| **Inputs** | `raw` (string, expected format `clientId\|clientSecret`) |
| **Outputs** | An `OidcAppCredentials` struct with `ClientId` and `ClientSecret` populated. |
| **Primary components** | `OidcAppCredentials..ctor(string)` |
| **Entry point** | `src/SAIF.NetCore.ServiceContracts/SAIF.NetCore.ServiceContracts/SAIF.NetCore.ServiceContracts/OidcAppCredentials.cs` |

## Steps

1. Check `raw` for null. ([BR-001](../business-rules.md#br-001-raw-oidc-credential-string-must-not-be-null))
   - On failure: throw `ArgumentNullException(nameof(raw))`; nothing is constructed.
2. Split `raw` on the `'|'` character.
3. Verify the split produced exactly two segments. ([BR-002](../business-rules.md#br-002-raw-oidc-credentials-must-be-two-pipe-delimited-segments))
   - On failure: throw `ArgumentException("Raw credential parameter does not contain valid credential data.")`. An empty string yields 1 part; `"a|b|c"` yields 3 parts — both throw.
4. Assign `ClientId = parts[0]` and `ClientSecret = parts[1]`. Empty segments are accepted (for example `"|"`). ([BR-002](../business-rules.md#br-002-raw-oidc-credentials-must-be-two-pipe-delimited-segments))

## Process flow

The following diagram visualizes this operation's control flow.

```mermaid
flowchart TD
	Start([Construct OidcAppCredentials]) --> NullCheck{raw is null?}
	NullCheck -->|Yes| ThrowNull([Throw ArgumentNullException])
	NullCheck -->|No| Split["Split raw on '|'"]
	Split --> CountCheck{Exactly 2 segments?}
	CountCheck -->|No| ThrowArg([Throw ArgumentException])
	CountCheck -->|Yes| Assign[Assign ClientId and ClientSecret]
	Assign --> End([Return populated struct])
```

## Failure and edge-case behavior

- `raw` is `null`: throws `ArgumentNullException`.
- `raw` splits into 1 or 3+ segments: throws `ArgumentException`.
- A segment is an empty string: accepted without error (e.g. `"|"` yields empty `ClientId` and `ClientSecret`).

## Related documentation
- [Operations and processes](../operations-processes.md)
- [Business rules](../business-rules.md)

## Sources
- `src/SAIF.NetCore.ServiceContracts/SAIF.NetCore.ServiceContracts/SAIF.NetCore.ServiceContracts/OidcAppCredentials.cs`
