# Review policy

> What Sollar reviews, what it rejects, how entity verification works and what a tenant-private app skips.

Source: https://miniapp.sollar.com/platform/review-policy/

---

## Who gets reviewed

**Store apps do. Tenant-private apps do not.**

That is a structural decision, not a courtesy. The central case this platform exists for is a
company building a mini app of its own ERP for its own employees. If every change to that ERP joined
a Sollar review queue, the platform would be unusable in a corporate setting — an internal release
cycle cannot depend on a vendor's service level.

Lark separates them the same way: self-built apps confined to one tenant with no Lark review, versus
store apps with official review. DingTalk does the same for enterprise-internal applications, where
an administrator creates the app under the `corpid` and grants its scopes without a platform gate.

Skipping review is not skipping cryptography. A tenant-private package is countersigned by the
organisation's CA, and Sollar's client refuses any package lacking a countersignature from either
the store or an organisation CA.

## Entity verification

To publish in the public store, a developer must be a verified entity.

| Type | May publish | Requires |
|---|---|---|
| Individual | Apps touching no sensitive data, no external auth | Verified identity |
| Organisation | Anything, subject to category | Business registration + a responsible contact |
| Tenant (private) | For itself only | Already a contracted customer |

Sensitive categories — health, finance, education involving minors — require additional
qualification. This is not decorative bureaucracy: it is what makes it possible to refuse a
"payroll advance loan" mini app from an entity with no licence to offer one.

The model follows WeChat's, which recognises six subject types, each enabling different service
categories and each requiring its own documents.

## The checklist

Every store submission is checked against all of this. Tenant-private packages are validated
mechanically against the same schema, without the human review.

### Manifest and permissions

1. The manifest validates against the published schema.
2. Every declared permission has a `purpose` that plausibly matches the app's stated function.
3. No permission is declared that the code never uses. **This catches more submissions than anything
   else** — a scope declared "in case we need it later" reads as over-collection, because it is.
4. Prompts appear at the point of use, not in a wall at launch.
5. Refusal produces a working degraded path, not a dead end or a re-prompt loop.

### Network and code

6. The network allowlist is justifiable. An unexplained host is a question to the developer, not an
   automatic rejection.
7. The CSP meets the floor: `script-src 'self'`, no `'unsafe-eval'`, no remote script host.
8. No `eval`, no `Function()`, no dynamically constructed code.
9. An SBOM is present and contains no high-severity known vulnerability.
10. No obfuscation that prevents review from reading what the code does.

### Actions

11. Every `actions[]` entry describes honestly what it does.
12. `destructive` is set where the effect is destructive. An action that releases an order to a
    vendor and is marked `read_only` is a rejection, and a serious one.
13. `confirm` is appropriate to the annotations. `never` with `read_only: false` is refused.
14. Descriptions do not attempt to steer an agent toward actions the user did not ask for.

### Content and conduct

15. Reporting and blocking are reachable from inside the mini app (Guideline 4.7.1).
16. A content rating is declared (4.7.5).
17. A privacy policy exists and covers what the permissions actually collect.
18. A monitored `vendor.contact`.

## Reasons for rejection

WeChat publishes a specific list, and several entries map directly onto abuse any mini app store has
to police. Quoted, because the wording is precise:

- *"诱导分享、诱导添加、诱导关注公众号、诱导下载等"* — induced sharing, adding, following or
  downloading; requiring a user to share before they can use the app.
- *"小程序的页面内容中不能存在虚假、欺诈类内容"* — false or fraudulent content, including fake prizes
  and campaigns.
- *"禁止视频、音乐、语音等多媒体的自动播放"* — automatic playback of video, music or audio is
  prohibited.
- *"不能做小程序导航，不能做小程序链接互推，小程序排行榜等"* — no navigation between mini apps, no
  cross-promotion, no ranking lists.

The last one deserves emphasis. A store where mini apps promote each other stops being a tool
directory and becomes an attention marketplace, and the tools lose.

Sollar adds three of its own:

- **A misleading manifest** — a permission whose `purpose` does not match the function.
- **Actions that lie about destructiveness.**
- **Any attempt to collect a user credential inside the runtime's WebView.** This one is not a
  warning and not a request for changes; it is a rejection and a look at everything else the
  developer has published.

## Approved is not published

Review approves; the developer decides when to publish. This is the Chrome Web Store's separation
and it is worth copying — it lets a release coordinate with a product launch, a campaign, or a
maintenance window.

With an expiry: **an unpublished approval lapses after 30 days.** Without that, old approvals
accumulate whose security context has since changed.

## Reporting and moderation

Guideline 4.7.1 requires that offered software *"include a method for filtering objectionable
material, a mechanism to report content and timely responses to concerns, and the ability to block
abusive users."*

Concretely:

- **Report** is reachable from inside any mini app, in the **host's chrome** — it does not depend on
  the mini app implementing it, because a malicious mini app would not.
- A user can block a mini app; an administrator can block one for the whole organisation.
- A published response time for reports.
- `vendor.contact` is mandatory in the manifest.

## Emergency revocation

Distinct from rollback. When a published version is dangerous:

1. A signed revocation list, consulted at launch, with a short TTL.
2. The client refuses to open the revoked version; if a safe version exists, it updates first.
3. If the whole app is revoked, it leaves the catalogue and installed copies stop opening.

The client has to work offline, so there is a window. A mini app with sensitive permissions can be
required to verify online at launch — declared in the manifest.

## What review cannot do

Stated plainly:

- **Review cannot verify an annotation.** Nothing proves an action marked `read_only` really is. What
  review adds is that the claim is attributable to a key and cannot be changed silently afterwards.
- **Review reads a snapshot.** A mini app's backend can change its behaviour the day after approval.
  The manifest cannot — which is why capabilities live in the manifest and not in a server response.
- **Review is not an audit.** An approved mini app has passed a checklist, not a penetration test.

Nothing in this section has itself been through an independent audit; the platform is specified, not
built.
