Skip to content

Releases

v0.1.8

Choose a tag to compare

@Veloc1tyE Veloc1tyE released this 08 Nov 19:56

Assure engine e4ed4e8f, served by api.symbolia.ai. The Action built from it is Symbolia-Assurance/assure-action v0.1.8 (@v0 moves with it).

v0.1.8 changes no reading on Python or PostgreSQL apps and nothing in the Action. It prepares the TypeScript/Express reader, which is not served yet, to decide each route on its own.

Pin this release

      - uses: Symbolia-Assurance/assure-action@a8da838c8b725429cd9ce6d19de4657bacadaf96 # v0.1.8

For customers

  • TypeScript/Express (not served yet). When it is served, routes will be decided one at a time: a route whose mount chain, middleware and guards are fully read gets its reading, and a route the reader can't fully read is listed as refused, with the reason, beside the census's own completeness. The scope document says so.
  • Every served stack. Readings are unchanged from v0.1.7.

Where we are on the curve

  1. Decided-row reach on fresh apps: not re-measured at this release; v0.1.5 read 2 of 20 fresh FastAPI apps.
  2. Decided rows on real outside apps: not re-measured at this release (no served reader changed); v0.1.7 decided 26 of 821 rows across 94 public Python apps.
  3. False holds on the held-out corpus: no new false hold against v0.1.7 (0 regressions across 89 pre-release gate rows, held-out rows included); planted flaws caught as on v0.1.7 with 0 false alarms (Flask 4 of 15, Python 1 of 97, Node 3 of 37, Go 3 of 20); one coverage row (Python held-out rows, 4 of the 5 the gate asks for) accepted as an exception for this release.
  4. Usage-weighted coverage: 230 of 507 auth-relevant package uses (45.4%) across 184 apps have a formal model.
  5. Formal share of CI: not measured at this release; 18 of 18 PostgreSQL HBA-1 readings carry a Lean certificate.
  6. Tokens per verified change: 41.7 M including cache reads, 1.30 M excluding (24 h to 8 Nov 08:00 UTC); v0.1.5 baseline 17.9 M / 0.90 M.

Self-check

This release's record: https://symbolia.ai/self-check/e4ed4e8f (58 holds, 8 not established, 2 disproven, of 68). The current proof tree: https://symbolia.ai/self-check/latest.

Known issues

  • FastAPI: an app that defines or imports its own Depends or Security can make IDENT-1 read as holding on routes that are open.
  • Django: a helper that decodes and validates the identity proof, called only under a condition, can make IDENT-7 read as holding.
  • Django: an expiry checked through a helper, or a PyJWT decode with a small literal leeway, can read IDENT-7 as disproven on an app that bounds expiry.
  • Django: a jwt.decode call where jwt is a local object rather than the imported library can make IDENT-7 read as holding.
  • Django: a PyJWT 1.x decode passed verify=False, as a keyword or a third positional False, can make IDENT-7 read as holding.
  • FastAPI: a decode refused under the signature rules that falls through to a trusted header can make IDENT-9 read as holding.
  • FastAPI: a guard whose denial a helper it calls catches, or that wraps a raising helper in contextlib.suppress, can make IDENT-1 read as holding while the route is open.
  • Flask: a session signing value written in the repository can make AUTH-1 read as holding while a forged session reaches the view.
  • Django: REST framework settings loosened indirectly, through getattr with a variable name, attrgetter, vars(), a class-attribute alias, a walrus assignment or a match capture, can make IDENT-1 read as holding while anonymous requests succeed.
  • Django: a settings store through a local bound to an app-class call, a star import that rebinds that class, or a helper that returns settings state can make IDENT-1 read as holding while anonymous requests succeed.
  • Django: IDENT-7 can read the expiry as checked when the decode that checks it never runs or is not the library's: a verifier method the call chain never reaches, a decode after a return or whose expiry error is caught, a helper its own module rebinds, jwt re-exported from another module or wrapped by a decorator. An expired identity proof is then accepted.

v0.1.7

Choose a tag to compare

@Veloc1tyE Veloc1tyE released this 08 Nov 09:31

Assure engine 6a441ba1, served by api.symbolia.ai. The Action built from it is Symbolia-Assurance/assure-action v0.1.7 (@v0 moves with it).

v0.1.7 mostly corrects readings, fixes timeouts on long PostgreSQL migration histories and large Django apps, and reads more libraries. If your app has one of the shapes below, a check you ran on v0.1.6 may have read differently from what your code does. Run it again.

Pin this release

      - uses: Symbolia-Assurance/assure-action@0c7ee30c5b9b8346f70e6474c4f003f7deefaacb # v0.1.7

For customers

  • Django. Expiry is credited only through code that runs: not through a helper under a non-static or class-method decorator, a class method nothing reaches, a reach call on a rebound self, or a call that resolves to your own code. A store through a binding of library or settings state the reader cannot follow is refused, and pytest monkeypatch on a library name is read as a store. The first-run draft reads a bare LoginView sign-in, repository-read app keys and stored-value header comparisons as API-key credentials, and key-row deletion and declared revokers as revocation. A Django app the size of healthchecks reads in about 14 seconds, down from about 40 minutes.
  • FastAPI. Expiry evidence counts only where it always runs: in reached helpers, verifier classes, inner functions and lambdas. First-run IDENT-3 and declared IDENT-11 now decide where they read not_established. A cookie session id looked up in a database table drafts no credential.
  • Flask. A library pinned at a release the catalogue reads is read as that release's code, and guarded fallback imports and shell_context_processor are read.
  • Any Python stack. .decode(algorithms=) is credited only on the JWT module or a bare PyJWT(). A file Python's compiler rejects is named as a refusal. A first run with no stack named drafts the framework the repository uses, and a TypeScript/Express repository is refused rather than drafted as Flask. Nine more libraries are read: pyotp, google-auth, oauthlib, ldap3, jwcrypto, python-ldap, django-auth-ldap, argon2-cffi and pynacl.
  • PostgreSQL. A schema with about 150 migrations no longer times out. A declared PRIV-1 row on a table name two schemas share reads needs_intent, not a false fails, and a privilege query naming such a table is dropped with a warning. HBA, LISTEN and TLS baselines read PostgreSQL 15 and 16, and HBA-1 readings carry a Lean certificate. With the opt-in, the Action compares JSONB CHECK constraints with your committed schemas.
  • The Action. The summary names the stack it read, the log links the kept proposal branch, and a stored result is replayed only when the engine that produced it is still serving. Feedback is accepted without an API key and held apart until it is reviewed.

Where we are on the curve

  1. Decided-row reach on fresh apps: not re-measured at this release; v0.1.5 read 2 of 20 fresh FastAPI apps.
  2. Decided rows on real outside apps: 26 of 821 rows across 94 public Python apps (Django 20 of 517, FastAPI 6 of 141, Flask 0 of 163); v0.1.6 decided 14 of 733.
  3. False holds on the held-out corpus: no new false hold against v0.1.6 (0 regressions across 89 pre-release gate rows, held-out rows included); planted flaws caught as on v0.1.6 with 0 false alarms (one planted app left out of the comparison: v0.1.6 times out on it, v0.1.7 reads it); one coverage row (Python held-out rows, 4 of the 5 the gate asks for) accepted as an exception for this release.
  4. Usage-weighted coverage: 230 of 507 auth-relevant package uses (45.4%) across 184 apps have a formal model.
  5. Formal share of CI: not measured at this release; 18 of 18 PostgreSQL HBA-1 readings now carry a Lean certificate.
  6. Tokens per verified change: 23.4 M including cache reads, 0.95 M excluding (24 h to 8 Nov 05:00 UTC); v0.1.5 baseline 17.9 M / 0.90 M.

Self-check

This release's record: https://symbolia.ai/self-check/6a441ba1 (58 holds, 8 not established, 2 disproven, of 68). The current proof tree: https://symbolia.ai/self-check/latest.

Known issues

  • FastAPI: an app that defines or imports its own Depends or Security can make IDENT-1 read as holding on routes that are open.
  • Django: a helper that decodes and validates the identity proof, called only under a condition, can make IDENT-7 read as holding.
  • Django: an expiry checked through a helper, or a PyJWT decode with a small literal leeway, can read IDENT-7 as disproven on an app that bounds expiry.
  • Django: a jwt.decode call where jwt is a local object rather than the imported library can make IDENT-7 read as holding.
  • Django: a PyJWT 1.x decode passed verify=False, as a keyword or a third positional False, can make IDENT-7 read as holding.
  • FastAPI: a decode refused under the signature rules that falls through to a trusted header can make IDENT-9 read as holding.
  • FastAPI: a guard whose denial a helper it calls catches, or that wraps a raising helper in contextlib.suppress, can make IDENT-1 read as holding while the route is open.
  • Flask: a session signing value written in the repository can make AUTH-1 read as holding while a forged session reaches the view.
  • Django: REST framework settings loosened indirectly, through getattr with a variable name, attrgetter, vars(), a class-attribute alias, a walrus assignment or a match capture, can make IDENT-1 read as holding while anonymous requests succeed.
  • Django: a settings store through a local bound to an app-class call, a star import that rebinds that class, or a helper that returns settings state can make IDENT-1 read as holding while anonymous requests succeed.
  • Django: IDENT-7 can read the expiry as checked when the decode that checks it never runs or is not the library's: a verifier method the call chain never reaches, a decode after a return or whose expiry error is caught, a helper its own module rebinds, jwt re-exported from another module or wrapped by a decorator. An expired identity proof is then accepted.

v0.1.6

Choose a tag to compare

@Veloc1tyE Veloc1tyE released this 07 Nov 02:08

Assure engine 5feac4f4, served by api.symbolia.ai. The Action built from it is Symbolia-Assurance/assure-action v0.1.6 (@v0 moves with it).

v0.1.6 mostly corrects readings, and fixes three readings v0.1.5 listed as known issues. If your app has one of the shapes below, a check you ran on v0.1.5 may have read differently from what your code does. Run it again.

Pin this release

      - uses: Symbolia-Assurance/assure-action@40a54d6b9d89882a9dbb24f3616c0fbd2811531e # v0.1.6

For customers

  • FastAPI. A guard whose denial a handler swallows is no longer counted. An Authlib check replaced on the claims class gives no expiry credit. The first-run draft withholds routes it cannot read instead of drafting them public, and now drafts routes on prefixed routers, on apps or routers imported from another module, and in app factories, with HTTPBearer subclasses and imported API keys as credentials.
  • Django. A decode with options, a leeway, or options that are not written inline gives no expiry credit, and neither does jwt.api_jws.decode. A validate() counts only when it always runs and covers every decode. Test patches of the identity library through mock.patch and related forms are read. The first-run draft handles a project below the repository root, router-registered viewsets and middleware guards.
  • Any Python stack. A handler with a return before its raise is not counted as "every handler raises".
  • Observed PostgreSQL. Eleven new CVE rows and five login rows are read.

Where we are on the curve

  • Real outside apps read through the API: 2 of 19 Python corpus apps get a reading; the rest name the line Assure could not read (v0.1.6 adds no new reads; scoped reading is the next unit).
  • Pre-release corpus gate: 0 regressions across 89 rows, held-out rows included (gate 16725).

Known issues

  • FastAPI: an app that defines or imports its own Depends or Security can make IDENT-1 read as holding on routes that are open.
  • FastAPI and Django: a helper that decodes and validates the identity proof, called only under a condition, can make IDENT-7 read as holding.
  • Django: a jwt.decode call where jwt is a local object rather than the imported library can make IDENT-7 read as holding.
  • FastAPI: a decode refused under the signature rules that falls through to a trusted header can make IDENT-9 read as holding.
  • FastAPI: a guard whose denial a helper it calls catches, or that wraps a raising helper in contextlib.suppress, can make IDENT-1 read as holding while the route is open.
  • Flask: a session signing value written in the repository can make AUTH-1 read as holding while a forged session reaches the view.
  • Django: REST framework settings loosened indirectly, through getattr with a variable name, attrgetter, vars(), a class-attribute alias, a walrus assignment or a match capture, can make IDENT-1 read as holding while anonymous requests succeed.
  • Django: a settings store through a local bound to an app-class call, a star import that rebinds that class, or a helper that returns settings state can make IDENT-1 read as holding while anonymous requests succeed.
  • Django: IDENT-7 can read the expiry as checked when the decode that checks it never runs or is not the library's: a verifier method the call chain never reaches, a decode after a return or whose expiry error is caught, a helper its own module rebinds, jwt re-exported from another module or wrapped by a decorator. An expired identity proof is then accepted.

v0.1.5

Choose a tag to compare

@Veloc1tyE Veloc1tyE released this 01 Nov 06:08

Assure engine 32cfcef5, served by api.symbolia.ai. The Action built from it is Symbolia-Assurance/assure-action v0.1.5 (@v0 moves with it).

v0.1.5 mostly corrects readings. If your app has one of the shapes below, a check you ran on v0.1.4 may have read differently from what your code does. Run it again.

Pin this release

      - uses: Symbolia-Assurance/assure-action@d4a80a647c149551cc6b1605f565d250843d9800 # v0.1.5

For customers

  • FastAPI. Routes are no longer lost through app factories, aliases of add_api_route, route lists or routers declared in another module; where a composition can't be followed, the check refuses at that line. A guard replaced through dependency_overrides in an app factory no longer reads as holding. Named router dependencies, route-decorator dependencies and a dependency bound twice now read as what takes effect. Expiry evidence counts only when an exp check takes effect. The first-run draft covers more guard, route and key shapes.
  • Django. A DRF permission decorator applied outside api_view is no longer credited. Role guards proved from the source are recognised. The URL census reads more list forms and refuses the rest. The first-run draft covers class views, viewsets, simplejwt, session sign-in and sign-out, and repository permission classes.
  • Flask. A decorator between the route and the declared guard leaves the route unread. A blueprint before_request hook under a declared Flask-HTTPAuth guard is read as guarding its routes. A route that answers only under testing or debug is no longer a false alarm.
  • Any Python stack. A guard Assure does not recognise, on a route IDENT-3 or IDENT-5 judges, reads as not established and is named. A data-flow analysis that hits its limit fails closed.
  • Python standard-library servers. Routes added with |= and a second declared server are no longer left out.
  • Express and TypeScript. No file a route could live in is dropped. Unreadable wrappers mark the route unread, guards are followed through barrel re-exports, computed prefixes refuse, and middleware that only observes the signed-in user is not credited as a guard. One file that does not parse no longer refuses the whole check.
  • Go (gin). A session reset to anonymous is read, and a file is no longer skipped because of its path name.
  • Observed PostgreSQL. Declared administrators, sensitive_objects, privilege_queries and declared_predicate are read. New Supabase rows, TENANT-1 and TENANT-2, and a CVE-2021-23214 row are added. A constant-false SELECT policy no longer counts as a read policy.
  • Declared PostgreSQL. A tenant column compared through a varchar(N) cast no longer reads as holding. The first-run draft leaves unobserved replication settings unread and asks you.
  • Premium. A queued build is published, not rehearsed. An image in the repository no longer stops the construct. A Premium method you state is read on your next FastAPI or Django check.
  • Accounts. A daily records window per plan (100,000 on Premium, 500,000 on Pro), and an overage budget you set on the account.
  • The Action. Local mode runs under the runner's own Python and reads a Python checkout as API mode does. Several profiles or jobs on one PR share one comment, and older comments are marked superseded. Feedback the Action could not send is shown with one step to fix it.
  • Wording. Refusals and gaps name what fixes them more often, a 401 says when the value sent is not an Assure key, and the examples pin a commit.

Known issues

Nine readings can show as holding when they do not. The first three were present in v0.1.4. The fixes ship in v0.1.6.

  • FastAPI: a guard that catches its own HTTPException(403) can make IDENT-1 read as holding.
  • FastAPI first-run draft: a route registered with add_api_route and a Depends(<call>) it does not read can be drafted as public. Review drafted public routes before you accept them.
  • FastAPI: a decode refused under the signature rules that falls through to a trusted header can make IDENT-9 read as holding.
  • FastAPI: an app that defines or imports its own Depends or Security can make IDENT-1 read as holding on routes that are open.
  • FastAPI and Django: a validate() call inside a try whose error handler can return instead of raising can make IDENT-7 read as holding.
  • FastAPI and Django: a helper that decodes and validates the identity proof, called only under a condition, can make IDENT-7 read as holding.
  • Django: a PyJWT decode with a leeway above 300 seconds, or a leeway that is not a number literal, can make IDENT-7 read as holding.
  • Django: an Authlib jwt.decode counts as checking expiry whether or not validate() runs, so IDENT-7 can read as holding.
  • Django: a jwt.decode call where jwt is a local object rather than the imported library can make IDENT-7 read as holding.