Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/cd-publish-nuget-prerelease.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ name: CD - Publish NuGet Prerelease
# Asymmetric with `cd-publish-staging-image.yml`, which DOES auto-
# publish a Docker image on every develop merge. The reason:
#
# - Docker `:staging` is a moving pointer tag. Each push
# - Docker `:beta` is a moving pointer tag. Each push
# overwrites the previous one; the previous image becomes
# untagged and the GHCR retention rule deletes it. Cheap to
# update on every commit.
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/cd-release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,8 @@ name: CD - Release
# value — set a GHCR retention rule on `candidate-*` if cleanup matters.
#
# Sibling workflows for staging / prerelease / editorial doc paths:
# - cd-publish-staging-image.yml — pushes `:staging` Docker tag
# (auto on develop push + manual)
# - cd-publish-staging-image.yml — pushes `:beta` / `:<slug>` moving
# Docker tags (auto on develop push + manual)
# - cd-publish-nuget-prerelease.yml — prerelease NuGet for client-lib
# (manual workflow_dispatch)
# - cd-deploy-docs.yml — editorial doc deploy to Shelf
Expand Down
6 changes: 5 additions & 1 deletion dev-docs/future-features/app-resources-as-permissions.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,11 @@
> **Status der ursprünglichen Note:** Idea — captured 2026-05-07,
> refined 2026-05-08 with ID-anchored design (string-keyed
> `List<string>` rejected because RS-subsets and role-grants would
> drift on rename/delete). Not started.
> drift on rename/delete). **Shipped** — das ID-anchored Modell ist
> umgesetzt (`App.Permissions`-Catalog, `AppPermission.Id`,
> `PermissionRole.PermissionIds`, per-RS-Subset-Filterung,
> Claims-Flattening). Single-Source-of-Truth ist
> [`permission-modell.md`](./permission-modell).
> **Why:** While walking a user through OAuth-API setup we hit a
> conceptual cliff: the IdP's `App.Resources` field stores only the
> middle segment of a permission (`policy`, `knowledge`, `mcp`),
Expand Down
2 changes: 1 addition & 1 deletion dev-docs/future-features/federation-v1-design.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Federation v1 — Implementation Spec

Status: **Design decided (A–G settled, 2026-05-29), ready for an implementation plan. No code yet.** Concretizes the federation model decided in [identity-lifecycle-untangle](./identity-lifecycle-untangle#federation-prior-art) into real code seams. Based on integration map `wf_63933d9f-149`. Depends on Hotfix C (PR #21, `766c9f8`).
Status: **Shipped (spec PR #23 `4fa3af0`, implementation PR #24 `0b70b31`); durable leased-membership = deferred v2.** Login-time in-memory membership derivation, EvalPrincipal/ExternalGroups, the external claims store, and baking federated `resource_access` into the access token (hub-by-default + broker-opt-in) are all live with passing tests. The remaining v1↔v2 gap is the durable enumerable filter (see [v1 vs v2](#v1-vs-v2)). Concretizes the federation model decided in [identity-lifecycle-untangle](./identity-lifecycle-untangle#federation-prior-art) into real code seams. Based on integration map `wf_63933d9f-149`. Depends on Hotfix C (PR #21, `766c9f8`).

> **Background** (prior art, the stale-admin trap, the hub-vs-broker spectrum): see the [untangle doc](./identity-lifecycle-untangle). This doc is the build template.

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Federation v1 — Implementation Plan

Status: **Build-ready.** Concretizes [federation-v1-design](./federation-v1-design) (decisions A–G settled 2026-05-29) into an ordered, file:line-accurate build sequence. Every seam below was re-verified against the working tree at `dev-docs/federation-v1-design` HEAD `a57ee04` (which includes Hotfix C, PR #21, `766c9f8`) by a 7-agent read-only verification pass (`wf_5ba83c8c-b9e`, raw findings in `.local/`). The design is decided; this document is the **how and in what order**, not a re-litigation of A–G.
Status: **Shipped (Phases 0–5 + v1.1).** Implemented and merged to develop via PR #24 (squash `0b70b31`, 2026-05-29) — the phase breakdown below is the as-built record. Only Phase 6 (per-realm session TTL, decision E) and the v2 slice (durable leased external-membership) remain. Concretizes [federation-v1-design](./federation-v1-design) (decisions A–G settled 2026-05-29) into an ordered, file:line-accurate build sequence. Every seam below was re-verified against the working tree at `dev-docs/federation-v1-design` HEAD `a57ee04` (which includes Hotfix C, PR #21, `766c9f8`) by a 7-agent read-only verification pass (`wf_5ba83c8c-b9e`, raw findings in `.local/`). The design is decided; this document is the **how and in what order**, not a re-litigation of A–G.

> Read the [design spec](./federation-v1-design) first for the *why*. This plan assumes the model in one paragraph, the two-layer source filter, and decisions A–G as given.

Expand Down
2 changes: 1 addition & 1 deletion dev-docs/future-features/identity-lifecycle-untangle.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ Status: **mostly implemented** — original analysis/decision-gate pass from 202
- ❌ STILL OPEN (durable-lease, the large piece): replace the flat `Group.MemberIds: List<Guid>` with a source-attributed external-membership class `(groupId, principalId, source = provider:<slug>, grantedAt, leaseExpiresAt, lastReconfirmedAt)`; effective members = union of { manual } + { local-JsEval } + { per-provider external WHERE leaseExpiresAt > now }. Federation v1 shipped only the *session-scoped* derivation ("the session is the lease"); this is the durable, login-independent version.
- ❌ STILL OPEN: refresh triggers — login-FORCE SET-reconcile, lease-expiry sweep (Quartz, fail-closed), optional inbound SCIM / scheduled LDAP-or-Graph pull (net-new surface).
- ✅ Privilege guardrail (federated/JsEval auto-membership must never confer `realm:admin`) is already enforced by Federation v1 decision G (bidirectional config guard + `ExpandBypassTiers` strip).
- ❌ STILL OPEN: resolve the `docs/concepts/auto-membership.md` `externalClaims`/`OrganizationalUnit`/`Department` doc-vs-code contradiction (the spec of the wanted, unbuilt durable-claims surface).
- ✅ RESOLVED (PR #24): the `docs/concepts/auto-membership.md` `externalClaims`/`OrganizationalUnit`/`Department` doc-vs-code contradiction is closed — the misleading examples were replaced by the shipped `ExternallyDrivable`-group + `p.ExternalGroups` surface (session-scoped federation deriver), and the durable-fields table now explicitly states there is no `OrganizationalUnit`/`Department`/`externalClaims`. (The *durable, login-independent* claims surface remains the Phase-4-large durable-lease piece above.)

**Known low-pri follow-up (surfaced by the Phase-3 adversarial review):**

Expand Down
16 changes: 11 additions & 5 deletions dev-docs/future-features/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ Severity. Detail-Pages unten.

⭐ **Federation v1 — implementation spec (2026-05-29):**
[federation-v1-design](./federation-v1-design)
— concretizes the agreed v1 model into real code seams (one seam: `ExternalLoginProcessor.ProcessAsync`; authz resolved late at token time): the unified claims-per-source store, the two-layer source filter, "session = lease" (mid-session timer rejected), the new per-provider/per-group flags. All design decisions A–G are settled; the doc is the build template.
— concretizes the agreed v1 model into real code seams (one seam: `ExternalLoginProcessor.ProcessAsync`; authz resolved late at token time): the unified claims-per-source store, the two-layer source filter, "session = lease" (mid-session timer rejected), the new per-provider/per-group flags. All design decisions A–G are settled; the doc is the build template. **✅ Shipped (PR #23 spec, PR #24 `0b70b31` broker → session-derived authz + v1.1 token layer).**

### Audit-Followups (in Severity-Reihenfolge)

Expand All @@ -35,8 +35,8 @@ Severity. Detail-Pages unten.
- [SAML federation — implementation plan](./saml-federation) —
konkreter Implementation-Plan für den SP-Use-Case (Modgud konsumiert
Customer-IdP). Lib-Wahl: ITfoxtec.Identity.Saml2. Status:
Decisions captured 2026-05-27, in active development on
`feat/saml-federation`.
✅ Shipped (PR #17, `8fc3df0`) — SAML 2.0 SP federation +
login-provider single-modal Add+Edit.
- [SAML AMR → `amr` wiring](./saml-amr-wiring) — `SamlFlavorData.AmrMapping`
is configured/seeded but parsed-but-not-consumed (federation v1 deferral
I15). Captures what the read-side wiring would do and why deferring is
Expand All @@ -61,7 +61,11 @@ Per-realm theming: logo, colors, brand copy, optional custom CSS.
custom copy → custom CSS), with a phased rollout plan that ships
the 80%-coverage version first.

**Status:** Design captured 2026-05-07. Not started.
**Status:** ✅ Phase 1 shipped — per-realm token-based branding
(`BrandingSettings`), asset library (BYTEA store, anonymous
`/api/assets/{id}` read), Branding/Pages/PageEditor admin views
(`8c8dea5`, `2ec0e58`, `ae2f9ca`). Page-builder runtime rendering still
deferred; custom-CSS tier not started.

### [Service Account credentials — link to OAuth Clients](./service-account-credentials)

Expand Down Expand Up @@ -180,7 +184,9 @@ Emission verworfen (UserInfo-Emission stattdessen), Bypass-Tiers
auf 2 reduziert, Slug-tagged-Format auf bare reduziert. Diese Note
bleibt als Designexploration — Detail-Banner oben in der Note.

**Status:** Note 2026-05-07, teilweise revidiert 2026-05-08.
**Status:** Note 2026-05-07, teilweise revidiert 2026-05-08. ✅ Das
ID-anchored Permission-Modell ist implementiert (siehe
[Permission-Modell](./permission-modell)).

### DCR for MCP clients — ✅ shipped

Expand Down
8 changes: 5 additions & 3 deletions dev-docs/future-features/permission-modell.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,11 @@
> Jede **App** deklariert ihre vollständige **Permission-Liste** als
> Catalog im strikten Format `<resource>:<action>`; jeder **Resource
> Server** kriegt davon ein Subset zugewiesen; **`/connect/userinfo`
> emittiert per-Audience-nested Blocks mit Roles, Permissions und
> Groups** (Bypass-Tiers vom IdP vor-expandiert); Konsumenten lesen
> ihren Block über den Audience-Key und machen stumpfes exact-match.
> emittiert per-Audience-nested Blocks mit Roles und Permissions**
> (Bypass-Tiers vom IdP vor-expandiert; **Groups bleiben heute
> IdP-internal und werden nicht emittiert** — siehe §5); Konsumenten
> lesen ihren Block über den Audience-Key und machen stumpfes
> exact-match.

Ab hier alles im Detail.

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ Use-Case**, nicht auf „Drop-in-Replacement für Keycloak".

- Multi-Instance / HA (DataProtection + Caches + Rate-Limiter alle
In-Memory)
- Enterprise-SSO (kein SAML, kein LDAP/AD)
- Enterprise-SSO (SAML 2.0 SP ✅ seit 2026-05-28 / PR #17; LDAP/AD weiter offen)
- Fremde Kunden mit Compliance-Audit (kein SOC2/ISO27001)
- Mehr als ~10 aktive Realms ohne eigenes Backup-Tooling

Expand Down Expand Up @@ -55,7 +55,7 @@ Produkte.
| 2a | Deployment-Hygiene (DataProtection persistent + Wolverine-Mode-Toggle) | HIGH | [ha-multi-instance](./ha-multi-instance) | ✅ **DONE 2026-05-13** |
| 2b | Echte HA / Multi-Instance (Cross-Instance Pub/Sub, Distributed Caches) | HIGH | [ha-multi-instance](./ha-multi-instance) | ⏸ Deferred — braucht echtes Multi-Box-Setup zum Testen |
| 3 | Realm-Backup / Restore / DR-Tooling (N Tenant-DBs) | MEDIUM | [realm-backup-restore](./realm-backup-restore) | Captured |
| 4 | Enterprise-SSO: SAML 2.0 + LDAP/AD-Federation | MEDIUM | [enterprise-sso-saml-ldap](./enterprise-sso-saml-ldap) | Captured |
| 4 | Enterprise-SSO: SAML 2.0 + LDAP/AD-Federation | MEDIUM | [enterprise-sso-saml-ldap](./enterprise-sso-saml-ldap) | SAML 2.0 SP ✅ **DONE 2026-05-28** (PR #17 `8fc3df0`) · LDAP/AD weiter Captured |
| 5 | Brute-Force Visibility (Login-Alerts + manuelle IP-Blacklist) | MEDIUM | [login-alerts-ip-blacklist](./login-alerts-ip-blacklist) | Captured (2026-05-07) |
| 6 | Per-Realm Branding / Theming | LOW | [white-label-customization](./white-label-customization) | ✅ **DONE Phase 1 2026-05-13** ([Branding](/plattform/branding), [Asset Library](/plattform/assets), [Pages Beta](/plattform/pages)) |
| 7 | HSM / KMS Integration für Signing-Keys | LOW | (offen — siehe Audit-Note unten) | Captured-here |
Expand Down Expand Up @@ -108,7 +108,7 @@ ein Enterprise-Kunde es fordert. Aufwand: Mannmonate, nicht Tage.
| Password + Lockout | 4 | 4 | 5 | 4 |
| 2FA Breadth | **5** | 4 | 5 | 5 |
| External IdP Federation (OIDC) | 3 | 5 | 5 | 5 |
| SAML / LDAP / AD | **1** | 5 | 5 | 4 |
| SAML / LDAP / AD | **3** (SAML 2.0 SP ✅ seit 2026-05-28, PR #17; LDAP/AD weiter offen) | 5 | 5 | 4 |
| RBAC Granularity | 4 | 4 | 4 | 5 |
| ABAC / Policy-Engine | 2 (extern) | 3 | 4 | 4 |
| Multi-Tenancy-Modell | 4 (DB-per-Realm) | 4 | 5 | 5 |
Expand Down
2 changes: 1 addition & 1 deletion dev-docs/future-features/saml-federation.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ title: SAML federation — implementation plan

# SAML federation — implementation plan

> **Status:** Plan captured 2026-05-27. Not started. Chosen as the post-v0.5.0 feature wave.
> **Status:** Shipped (PR #17, commit 8fc3df0). SAML 2.0 SP is live in develop — SamlLoginFlow, DynamicSamlSchemeManager, fully-wired SamlEndpoints (metadata/login/ACS), flavor presets, cert service, metadata refresh, frontend SAML tabs. Single-Logout (SLO) and SAML IdP-mode remain explicitly out of v1 scope (deferred — see [Out](#out-this-wave) / [open questions](#open-questions)). Plan captured 2026-05-27; chosen as the post-v0.5.0 feature wave.
> **Why:** Enterprise customers (especially anyone with ADFS or pre-cloud Salesforce/ServiceNow) need SAML 2.0 to even put Modgud on their evaluation list. Today Modgud federates only over OIDC. SAML is the gating capability for the next class of customer conversations.
> **Scope of *this* plan:** SAML SP only — Modgud accepts SAML assertions *from* a customer IdP. SAML IdP mode (Modgud emits SAML to legacy apps) is parked, see [open questions](#open-questions).

Expand Down
18 changes: 11 additions & 7 deletions dev-docs/future-features/userinfo-hybrid-flat-emission.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
# UserInfo Hybrid-Emission — integriert in das Hauptmodell

> **Status:** Integriert. Siehe [Permission-Modell](./permission-modell)
> §5 für die finale Architektur. UserInfo emittiert **immer**
> per-Audience-nested Blocks mit `permissions`/`roles`/`groups`,
> Bypass-Tiers vom IdP vor-expandiert. Diese Note bleibt nur als
> Designgeschichte bestehen.
> **Status:** Die hier skizzierte **flache Single-Audience-Emission
> wurde verworfen**, nicht gebaut. Geshipped ist die **nested
> per-Audience**-Variante: UserInfo emittiert
> `resource_access[<aud>]`-Blocks mit `permissions`/`roles`,
> per-Scope gegated, Bypass-Tiers vom IdP vor-expandiert. `groups`
> wird **nicht** emittiert (IdP-internal). Siehe
> [Permission-Modell](./permission-modell) §5 für die finale
> Architektur. Diese Note bleibt nur als Designgeschichte bestehen.

## Ursprüngliche Idee (überholt)

Expand All @@ -15,8 +18,9 @@ emittieren könnte für Lib-less-Konsumenten — als opt-in-Optimierung.

## Was am Ende gilt

UserInfo trägt **standardmäßig** Roles + Permissions + Groups, nicht
nur als optionale Hybrid-Emission. Der Audience-Key macht
UserInfo trägt **standardmäßig** Roles + Permissions (Groups bleiben
IdP-internal und werden nicht emittiert), nicht nur als optionale
Hybrid-Emission. Der Audience-Key macht
RS-Filterung sauber, die Bypass-Pre-Expansion macht
Lib-less-Konsumenten zur First-Class-Option. Die Annahme dass
„Distribution-API der einzige Authz-Kanal" sein müsse hat sich nicht
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ title: Versioning & Publishing Conventions

# Versioning & Publishing Conventions

> **Status:** Designed 2026-05-28 (split out of [[pr-image-build-on-comment]] when the `/build-image` comment-trigger was deferred but the tag/version rules became a must). Reviewed + revised 2026-05-28. Not yet implemented.
> **Status:** Designed 2026-05-28 (split out of [[pr-image-build-on-comment]] when the `/build-image` comment-trigger was deferred but the tag/version rules became a must). Reviewed + revised 2026-05-28. **Shipped** — GHCR retention (`cd-ghcr-retention.yml`, weekly cron + real prune), moving Docker tags (`cd-publish-staging-image.yml`) and the NuGet prerelease feed-gate to develop (`cd-publish-nuget-prerelease.yml`) are all live workflows.
> **Goal:** One version string across the artifact surfaces that *can* carry it (Docker tag, NuGet PackageVersion, AssemblyInformationalVersion), so "which image goes with which package?" is trivial — and clear rules for *where* each build is published, given that some surfaces are permanent and some are cleanable, and that anonymous pull is only possible from some.

## The single version string
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,10 @@ namespace Modgud.Api.Features.Auth.OAuth;

/// <summary>
/// Minimal-API endpoints for the OpenIddict server: authorize, token, userinfo,
/// logout. This is the porting baseline for stage 3b — it carries enough to
/// satisfy the OpenIddict pipeline (discovery + JWKS work, sign-in/sign-out flow
/// compiles end-to-end), but role + custom-claim injection is intentionally
/// deferred (legacy <c>IRoleRepository</c> / <c>IEffectiveRolesService</c> don't
/// exist in the new authorization model — that bridging is a follow-up phase).
/// logout. Role + permission and custom-claim injection are fully wired:
/// <see cref="CreateClaimsPrincipalAsync"/> builds the principal and per-audience
/// <c>resource_access</c> block via <see cref="IPermissionService"/>, then stamps
/// claim destinations with <c>SetDestinations</c>.
/// </summary>
public static class AuthorizationEndpoints
{
Expand Down
4 changes: 2 additions & 2 deletions src/dotnet/Modgud.Api/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,7 @@
var configManager = builder.GetCocoarConfigManager();
var conf = configManager.GetConfig<StartUpConfiguration>();

if (!string.IsNullOrWhiteSpace(conf.CertPath))

Check warning on line 134 in src/dotnet/Modgud.Api/Program.cs

View workflow job for this annotation

GitHub Actions / Analyze (csharp)

Dereference of a possibly null reference.

Check warning on line 134 in src/dotnet/Modgud.Api/Program.cs

View workflow job for this annotation

GitHub Actions / Backend Build & Test

Dereference of a possibly null reference.
{
var certPath = PathHelper.GetFullPath(conf.CertPath);
var cert = X509CertificateLoader.LoadPkcs12FromFile(certPath, conf.CertPassword,
Expand Down Expand Up @@ -169,8 +169,8 @@
{
foreach (var entry in allowed.Split(',', StringSplitOptions.RemoveEmptyEntries | StringSplitOptions.TrimEntries))
{
if (Microsoft.AspNetCore.HttpOverrides.IPNetwork.TryParse(entry, out var network))

Check warning on line 172 in src/dotnet/Modgud.Api/Program.cs

View workflow job for this annotation

GitHub Actions / Analyze (csharp)

'IPNetwork' is obsolete: 'Please use System.Net.IPNetwork instead. For more information, visit https://aka.ms/aspnet/deprecate/005.' (https://aka.ms/aspnet/deprecate/005)

Check warning on line 172 in src/dotnet/Modgud.Api/Program.cs

View workflow job for this annotation

GitHub Actions / Backend Build & Test

'IPNetwork' is obsolete: 'Please use System.Net.IPNetwork instead. For more information, visit https://aka.ms/aspnet/deprecate/005.' (https://aka.ms/aspnet/deprecate/005)
options.KnownNetworks.Add(network);

Check warning on line 173 in src/dotnet/Modgud.Api/Program.cs

View workflow job for this annotation

GitHub Actions / Analyze (csharp)

'ForwardedHeadersOptions.KnownNetworks' is obsolete: 'Please use KnownIPNetworks instead. For more information, visit https://aka.ms/aspnet/deprecate/005.' (https://aka.ms/aspnet/deprecate/005)

Check warning on line 173 in src/dotnet/Modgud.Api/Program.cs

View workflow job for this annotation

GitHub Actions / Backend Build & Test

'ForwardedHeadersOptions.KnownNetworks' is obsolete: 'Please use KnownIPNetworks instead. For more information, visit https://aka.ms/aspnet/deprecate/005.' (https://aka.ms/aspnet/deprecate/005)
}
}
// ForwardLimit caps the X-Forwarded-* depth — defence against a
Expand All @@ -181,8 +181,8 @@
{
// Dev convenience: trust loopback so localhost reverse-proxies
// (Vite, Docker port-forwards) work without ENV setup.
options.KnownNetworks.Add(new Microsoft.AspNetCore.HttpOverrides.IPNetwork(System.Net.IPAddress.Parse("127.0.0.0"), 8));

Check warning on line 184 in src/dotnet/Modgud.Api/Program.cs

View workflow job for this annotation

GitHub Actions / Analyze (csharp)

'IPNetwork' is obsolete: 'Please use System.Net.IPNetwork instead. For more information, visit https://aka.ms/aspnet/deprecate/005.' (https://aka.ms/aspnet/deprecate/005)

Check warning on line 184 in src/dotnet/Modgud.Api/Program.cs

View workflow job for this annotation

GitHub Actions / Analyze (csharp)

'ForwardedHeadersOptions.KnownNetworks' is obsolete: 'Please use KnownIPNetworks instead. For more information, visit https://aka.ms/aspnet/deprecate/005.' (https://aka.ms/aspnet/deprecate/005)

Check warning on line 184 in src/dotnet/Modgud.Api/Program.cs

View workflow job for this annotation

GitHub Actions / Backend Build & Test

'IPNetwork' is obsolete: 'Please use System.Net.IPNetwork instead. For more information, visit https://aka.ms/aspnet/deprecate/005.' (https://aka.ms/aspnet/deprecate/005)

Check warning on line 184 in src/dotnet/Modgud.Api/Program.cs

View workflow job for this annotation

GitHub Actions / Backend Build & Test

'ForwardedHeadersOptions.KnownNetworks' is obsolete: 'Please use KnownIPNetworks instead. For more information, visit https://aka.ms/aspnet/deprecate/005.' (https://aka.ms/aspnet/deprecate/005)
options.KnownNetworks.Add(new Microsoft.AspNetCore.HttpOverrides.IPNetwork(System.Net.IPAddress.IPv6Loopback, 128));

Check warning on line 185 in src/dotnet/Modgud.Api/Program.cs

View workflow job for this annotation

GitHub Actions / Analyze (csharp)

'IPNetwork' is obsolete: 'Please use System.Net.IPNetwork instead. For more information, visit https://aka.ms/aspnet/deprecate/005.' (https://aka.ms/aspnet/deprecate/005)

Check warning on line 185 in src/dotnet/Modgud.Api/Program.cs

View workflow job for this annotation

GitHub Actions / Analyze (csharp)

'ForwardedHeadersOptions.KnownNetworks' is obsolete: 'Please use KnownIPNetworks instead. For more information, visit https://aka.ms/aspnet/deprecate/005.' (https://aka.ms/aspnet/deprecate/005)

Check warning on line 185 in src/dotnet/Modgud.Api/Program.cs

View workflow job for this annotation

GitHub Actions / Backend Build & Test

'IPNetwork' is obsolete: 'Please use System.Net.IPNetwork instead. For more information, visit https://aka.ms/aspnet/deprecate/005.' (https://aka.ms/aspnet/deprecate/005)

Check warning on line 185 in src/dotnet/Modgud.Api/Program.cs

View workflow job for this annotation

GitHub Actions / Backend Build & Test

'ForwardedHeadersOptions.KnownNetworks' is obsolete: 'Please use KnownIPNetworks instead. For more information, visit https://aka.ms/aspnet/deprecate/005.' (https://aka.ms/aspnet/deprecate/005)
}
});

Expand Down Expand Up @@ -624,8 +624,8 @@
builder.Services.AddScoped<ExternalLoginProcessor>();
builder.Services.AddHostedService<OidcSchemeBootstrap>();

// SAML SP federation (placeholder hook — incremental wiring lands
// in subsequent commits on feat/saml-federation).
// SAML SP federation (cert services, login flow, scheme manager,
// bootstrap + metadata-refresh hosted services).
builder.Services.AddModgudSaml();

// SETUP-01 / Setup endpoint surface eliminated in C15d. First-admin
Expand All @@ -646,7 +646,7 @@
var c = configManager.GetConfig<EmailConfiguration>();
return new PostmarkEmailServiceOptions
{
ServerToken = c.Postmark.ServerToken,

Check warning on line 649 in src/dotnet/Modgud.Api/Program.cs

View workflow job for this annotation

GitHub Actions / Analyze (csharp)

Dereference of a possibly null reference.

Check warning on line 649 in src/dotnet/Modgud.Api/Program.cs

View workflow job for this annotation

GitHub Actions / Backend Build & Test

Dereference of a possibly null reference.
FromAddress = c.Postmark.FromAddress,
FromName = c.Postmark.FromName,
MessageStream = c.Postmark.MessageStream,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,8 @@ namespace Modgud.Authentication.Api.ExternalAuth.Saml;
/// </para>
/// <para>
/// Single-Logout (SLO) is explicitly out of scope for v1 — see
/// <c>dev-docs/future-features/saml-federation.md</c>. The handlers below are
/// stubs returning 501 NotImplemented; the actual SAML protocol flow lands in
/// the ACS-integration commit (task #14 on feat/saml-federation).
/// <c>dev-docs/future-features/saml-federation.md</c>. The handlers below
/// (SpMetadata / Login / Acs) delegate to the live <c>SamlLoginFlow</c>.
/// </para>
/// </summary>
public static class SamlEndpoints
Expand Down
4 changes: 0 additions & 4 deletions src/dotnet/Modgud.Authentication/Setup/SamlSetup.cs
Original file line number Diff line number Diff line change
Expand Up @@ -72,10 +72,6 @@ public static IServiceCollection AddModgudSaml(this IServiceCollection services)
// IdPs advertise the new key from.
services.AddHostedService<SamlMetadataRefreshService>();

// Still to come in subsequent commits on feat/saml-federation:
// - SP cert generation / rotation services (task #13)
// - Real ACS / login / metadata endpoint logic (task #14)
// - Metadata refresh hosted service (task #15)
return services;
}
}
Loading