Osy#betaRun it on Osyrin: osyrin.com

Reference / Security

[Intended] — acknowledging an osy explain finding

[Intended("<finding>", Justification = "<why>")] — on a page (component) or a topic

`osy explain` flags a few postures with ⚠ — a public page whose data the public cannot read, a topic open to signed-out callers, a join rule that never asks who. Some of them are deliberate. `[Intended("<finding>", Justification = "…")]` on the page or topic records that decision with its reason: the report still lists the finding, marked as intended and carrying the reason, and stops counting it as open.

preview1 example compiled by CIsecurityexplainauditattribute

Summary#

osy explain is the report a reviewer reads to answer who can reach what. Besides stating every rule, it flags the places where a page's or a topic's access looks wrong. When one of those is what you meant, say so where it is declared, and say why:

[Intended("public-page-gated-data", Justification = "Visitors see the welcome; members see the notes.")]
[AllowAnonymous, Route("/")]
component Welcome() { … }

The finding is still in the report — as ✓ intended, with your reason beside it — and the count at the top of the report reads 0 open.

Signature#

[Intended("<finding>", Justification = "<why>")]   // on a component (a page) or a topic — one per finding
on<finding>flagged when
a pagepublic-page-gated-dataan [AllowAnonymous] page reads an entity a signed-out visitor may not read
a pagepage-auth-broader-than-dataa page any signed-in user may open reads an entity gated by a role or policy
a pagereads-ungranted-entitya page reads an entity that grants read to nobody
a topictopic-open-to-anonymousan [AllowAnonymous] topic: a caller with no account may join and publish
a topiccandidates-ask-nothing-about-whoits Candidates never reads the caller, so it answers the same for everyone
a topicpublishers-ask-nothing-about-whoits Publishers never reads the caller

Description#

It acknowledges; it does not hide#

An acknowledged finding stays in the Markdown and in osy explain --json. The Markdown says it as decided:

- **Reads** — Note
  - ✓ intended — 'Welcome' is public ([AllowAnonymous]) but 'Note' is not anonymously readable — the page renders
    and the read returns zero rows (a silent empty page). _Acknowledged (`public-page-gated-data`): Visitors see the
    welcome; members see the notes._

and the JSON carries the reason on the finding ("acknowledged": "Visitors see the welcome; …"), with the report's openFindings and acknowledgedFindings beside it. So a reviewer reads the posture and the decision together, and a report with zero open findings is one where every flag was looked at — not one where flags were switched off.

One finding, with a reason#

The mark names exactly one finding, so a different one that appears on the same page later is not acknowledged in advance; write one [Intended] per finding you mean. The reason is required. An [Intended] that names no finding the page or topic can carry is refused with the list above; one with no Justification is refused, because the reason is what the report prints.

A mark that no longer matches is reported#

If the page stops having the finding — the entity became readable, the page gained a gate — the mark is left acknowledging nothing. The report flags it as open (stale-acknowledgement): delete it, or it will quietly acknowledge the next finding of that kind.

What it is not for#

  • A sentence marked (needs review) is the report failing to phrase a rule — the platform's to fix, not yours to accept — and no attribute applies to it.
  • An osy lint finding is decided with [SuppressWarning("<rule>")] (a MUST-tier one cannot be). An [Intended] naming a lint rule is refused, saying so.
  • It changes nothing about who can do what. Access is still exactly what the rules say.

Examples#

[Principal] entity User {
  [Unique, MaxLength(200)] string Email;
  security { allow read when IsAuthenticated; }
}

entity Note {
  [MaxLength(200)] string Body = "";
  security { allow read when IsAuthenticated; }
}

[Intended("public-page-gated-data", Justification = "Visitors see the welcome; members see the notes.")]
[AllowAnonymous, Route("/")]
component Welcome() {
  render {
    Stack {
      Text("Welcome.");
      foreach (var n in Note.ToList()) { Text(n.Body); }
    }
  }
}

class StatusLine { public string Text = ""; }

[Intended("topic-open-to-anonymous", Justification = "The service status banner is public by design.")]
[AllowAnonymous]
topic ServiceStatus() {
  Candidates = u => u == null || u.Email != "";
  Carries    = StatusLine;
}

osy explain on it opens with > **Findings:** 0 open · 2 acknowledged as intended.

See also#

Related

Explaining your app's security

Explains your app's declared authorization in plain English — who can read, create, update and delete each entity…

secure by default (deny-all)

Deny-all is the posture, and it is the only one: an entity that declares no `security { }` block is denied to every…

public pages (what a signed-out visitor can see and do)

A public page, its public data, its public actions and its live updates are four separate declarations…

topic

A topic is a named, addressable realtime destination: a declared place to put a message so that every open page…

Checking your app

Checks your app against production best-practice rules and reports where it falls short — the maturity signal, beside…