Public Access
Moves the scaffold to src/DodoSSH.Api and establishes the repo conventions the rest
of the milestones build on.
Structure:
- src/{Contracts,Crypto,Domain,Infrastructure,Api}, tests/{Contracts,Crypto,Domain}.Tests
- DodoSSH.slnx rewritten with src/ and tests/ solution folders
Build:
- Directory.Build.props centralises TFM, nullable, deterministic builds and
TreatWarningsAsErrors; Directory.Packages.props pins every version centrally
- packages.lock.json committed so CI restores in locked mode
- NuGet.config clears machine-level sources, which both fixes NU1507 under central
package management and makes restore reproducible off this machine
- Microsoft.OpenApi pinned to 2.11.0: ASP.NET Core 10.0.10 resolves 2.0.0, which is
covered by GHSA-v5pm-xwqc-g5wc (high, patched in 2.7.5)
Analyzers:
- AnalysisLevel is Recommended, not All. With warnings-as-errors, All turns opinionated
naming rules into build breaks and trains people to blanket-suppress.
- BannedSymbols.txt bans DateTime.UtcNow (TimeProvider), Guid.NewGuid (CreateVersion7),
sync-over-async, MD5/SHA1, PBKDF2 and SecureString
- CA1711/CA1724 disabled: both are .NET Framework CAS-era naming rules
- PublicApiAnalyzers on Contracts only, since that assembly is the client's real contract
API:
- weather-forecast template removed
- UseHttpsRedirection removed; TLS terminates at the reverse proxy and redirecting
behind one causes loops
- /healthz/{live,ready,startup}. Liveness deliberately checks no dependencies so a
transient database outage cannot restart the container and kill live SSH sessions.
Notes:
- No coverage collector yet. Microsoft.Testing.Extensions.CodeCoverage pulls an MTP 1.x
MSBuild extension that throws TypeLoadException against the MTP 2.3.x xunit.v3 brings.
Coverage gates are an M3 concern; revisit with an MTP 2.x-aligned version then.
Verified: dotnet build (0 warnings), 17 tests pass, format check clean, API serves
health and OpenAPI endpoints.
43 lines
2.7 KiB
Plaintext
43 lines
2.7 KiB
Plaintext
# Banned APIs, enforced by Microsoft.CodeAnalysis.BannedApiAnalyzers (RS0030).
|
|
# Format: <documentation-comment-id>;<message>
|
|
# See docs/adr/ for the reasoning behind each group.
|
|
|
|
## Time — everything in DodoSSH is UTC and must be fakeable in tests.
|
|
P:System.DateTime.Now;Use TimeProvider.GetUtcNow(). All DodoSSH timestamps are UTC (timestamptz) and must be injectable for tests.
|
|
P:System.DateTime.UtcNow;Use TimeProvider.GetUtcNow() so time can be faked in tests.
|
|
P:System.DateTime.Today;Use TimeProvider.GetUtcNow().Date.
|
|
P:System.DateTimeOffset.Now;Use TimeProvider.GetUtcNow().
|
|
P:System.DateTimeOffset.UtcNow;Use TimeProvider.GetUtcNow() so time can be faked in tests.
|
|
|
|
## Identifiers — UUIDv7 gives sortable PKs with good index locality, and clients
|
|
## must be able to mint ids offline.
|
|
M:System.Guid.NewGuid;Use Guid.CreateVersion7() for sortable primary keys.
|
|
|
|
## Randomness — anything key-, token- or nonce-adjacent must be cryptographic.
|
|
T:System.Random;Use RandomNumberGenerator for anything security-relevant, or inject a seeded generator for tests.
|
|
|
|
## Sync-over-async — deadlocks under ASP.NET and stalls the Avalonia UI thread.
|
|
P:System.Threading.Tasks.Task`1.Result;Await the task instead; .Result deadlocks and hides exceptions in an AggregateException.
|
|
M:System.Threading.Tasks.Task.Wait;Await the task instead.
|
|
M:System.Threading.Tasks.Task.WaitAll;Use Task.WhenAll with await.
|
|
M:System.Threading.Tasks.Task.WaitAny;Use Task.WhenAny with await.
|
|
M:System.Threading.Tasks.Task.GetAwaiter;Await the task directly rather than blocking on the awaiter.
|
|
|
|
## Encoding — must be explicit, never the ambient codepage.
|
|
P:System.Text.Encoding.Default;Specify the encoding explicitly; Encoding.Default varies by platform.
|
|
|
|
## Culture-sensitive string handling is already covered by CA1304/CA1307/CA1311,
|
|
## which AnalysisLevel=latest-All turns on. Not duplicated here.
|
|
|
|
## Cryptography — the client holds key material in libsodium guarded memory, and
|
|
## MD5/SHA1 have no place in this product. Fingerprints are SHA-256.
|
|
T:System.Security.Cryptography.MD5;Banned. SSH fingerprints are SHA-256; see docs/crypto.md.
|
|
T:System.Security.Cryptography.SHA1;Banned. Use SHA-256 or better.
|
|
T:System.Security.Cryptography.Rfc2898DeriveBytes;PBKDF2 is not our KDF. Use Argon2id via DodoSSH.Crypto; see docs/crypto.md.
|
|
T:System.Security.SecureString;Deprecated and not cross-platform. Use a pooled byte[] zeroed with CryptographicOperations.ZeroMemory.
|
|
|
|
# Note: constant-time comparison of secrets (CryptographicOperations.FixedTimeEquals
|
|
# over Enumerable.SequenceEqual) is enforced by a BannedSymbols.txt scoped to
|
|
# DodoSSH.Crypto, not globally — banning SequenceEqual everywhere is pure noise in
|
|
# business logic and tests, and noisy bans just train people to suppress them.
|