---
title: Resolve data-protection certificate
summary: Finds the LocalMachine\My certificate used to encrypt the cookie data-protection key ring.
status: draft
owner: SAIF Framework Platform Team
last_reviewed: 2026-10-02
library: SAIF.NetCore.OIDC
reference_type: package
operation_id: OP-07
trigger: Called from OP-01 step 2
---

# Resolve data-protection certificate

| Field | Value |
| --- | --- |
| **Operation ID** | OP-07 |
| **Trigger** | Called from [Configure cookie authentication](op-01-configure-cookie-auth.md) step 2 |
| **Inputs** | `DPCertName` |
| **Outputs** | A certificate, `null` (developer machine), or an exception |
| **Primary components** | `DataProtectionCertService.GetCertificate` |
| **Entry point** | `src/SAIF.NetCore.OIDC/src/SAIF.NetCore.OIDC/Services/DataProtectionCertService.cs` |

## Steps

1. Open `X509Store(StoreLocation.LocalMachine)` (default store name `My`) read-only ([BR-OIDC-14](../business-rules.md#br-oidc-14-data-protection-certificate-must-match-subject-and-validity-window)).
2. Select a certificate where `Subject == DPCertName` and `NotBefore <= now < NotAfter` ([BR-OIDC-14](../business-rules.md#br-oidc-14-data-protection-certificate-must-match-subject-and-validity-window)) — `DPCertName` resolved via [Resolve OIDC settings](op-11-resolve-oidc-settings.md).
3. If found → return it.
4. If not found and **not** a developer machine (`IsDeveloperMachine()`, captured once in the constructor) → log Error and throw `MissingDataProtectionCertificateException(DPCertName)` ([BR-OIDC-15](../business-rules.md#br-oidc-15-a-missing-dp-certificate-is-fatal-outside-developer-machines)).
   - On failure: startup or first-request failure.
5. If not found on a developer machine → return `null` ([BR-OIDC-15](../business-rules.md#br-oidc-15-a-missing-dp-certificate-is-fatal-outside-developer-machines)).
   - On branch: keys are unprotected.

## Process flow

```mermaid
flowchart TD
	Start([GetCertificate called]) --> OpenStore["Open LocalMachine My store, read-only"]
	OpenStore --> Select["Select cert: Subject == DPCertName<br>and within validity window"]
	Select --> Found{Found?}
	Found -->|Yes| Return([Return certificate])
	Found -->|No| DevCheck{Developer machine?}
	DevCheck -->|No| Throw["Log Error; throw MissingDataProtectionCertificateException"]
	DevCheck -->|Yes| Null([Return null - unencrypted key ring])
```

## Failure and edge-case behavior
- A missing certificate is fatal on any non-developer machine, blocking cookie-options construction entirely.
- The developer-machine flag is captured once in the constructor (singleton lifetime), so a misdetected flag persists for the process lifetime.
- `DPCertName` must match the certificate `Subject` exactly; no partial or fuzzy matching is performed.

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

> **Note:** Statements marked with * were inferred from code structure, naming conventions, or
> contextual evidence where direct confirmation was not available in source artifacts. Statements
> marked with ** could not be confirmed; treat as unknown until verified.

## Sources
- `src/SAIF.NetCore.OIDC/src/SAIF.NetCore.OIDC/Services/DataProtectionCertService.cs`
