# missing-role-bootstrap

> An authenticated ShieldedAccessControl instance initializes but has no role-seeding route.

Canonical: https://nightshade.dicksonwu.xyz/rules/missing-role-bootstrap.html
Release: Nightshade 0.1.1 (v0.1.1)

| Field | Value |
| --- | --- |
| Rule ID | `missing-role-bootstrap` |
| Severity | low |
| Confidence | varies |
| Maturity | experimental |
| Selection | Audit default |
| Policy intent | not required |
| Default enabled | yes |
| Category | Audit-default ordinary rules |
| Engine facts used | resolved-calls, module-identities, constructor-histories |
| Release | v0.1.1 |

## Selection and scope

Selected by the default audit profile, so an ordinary scan runs it.

```sh
./.nightshade/node_modules/.bin/nightshade ./contracts --detectors missing-role-bootstrap
./.nightshade/node_modules/.bin/nightshade detector show missing-role-bootstrap
```

The first command runs only this rule; `--detectors` takes a comma-separated list. The second prints the rule's metadata from your installed version.

Severity is review priority. It does not express exploitability or impact. Confidence is detector metadata, not a probability. All built-in rules are experimental.

Compiler scope: the engine supports the pinned profiles 0.28.0, 0.29.0, 0.30.0, 0.31.1, 0.33.0-rc.2, 0.34.0, 0.35.0-rc.1 and 0.35.0, with ZKIR2 by default. Support for this rule can be narrower; the rule documentation below states any narrower scope.

## Corpus checks

Synthetic corpus checks for this rule in the 0.1.1 proof run. A check counts only with compiler acceptance and complete analysis.

| Positive detected | Corrected quiet | Lookalike quiet | Other negative quiet | Incomplete |
| ---: | ---: | ---: | ---: | ---: |
| 2/2 | 2/2 | 2/2 | 0/0 | 0 |

No deviations were recorded for this rule.

These are behavior checks on synthetic fixtures, not a precision or recall estimate. See [evaluation](https://nightshade.dicksonwu.xyz/evaluation.md#synthetic-corpus).

## Rule documentation

From https://github.com/DicksonWu654/nightshade/blob/v0.1.1/docs/detectors/missing-role-bootstrap.md at v0.1.1.

Availability: default-on; low severity, high confidence. Reports an authenticated
ShieldedAccessControl instance that initializes in every successful constructor
history but has no entry-reachable route to seed any role. With an empty role
tree, guarded `grantRole` cannot establish the first role holder.

### Example and scenario

```compact
import "access/ShieldedAccessControl" prefix SAC_;
constructor(salt: Bytes<32>) { SAC_initialize(salt); }
export circuit grant(role: SAC_RoleIdentifier, account: SAC_AccountIdentifier): [] {
  SAC_grantRole(role, account);
}
```

Initialization stores state and salt; it does not insert an initial role holder.
The library's documented constructor calls `_grantRole` separately.

### Recommendation

Seed an initial role holder, usually `DEFAULT_ADMIN_ROLE`, with `_grantRole` during
construction. Custom seeded roles and deliberate delayed setup are valid
alternatives. Review the intended administrator relationships separately.

### Evidence and known false positives

Requires compiler profile `compact-0.34.0-zkir2`, exact ShieldedAccessControl and
Utils source bytes from compact-contracts revision
`ec1331cd8195694c747d291e8fc8ab6d2914a976`, and complete successful constructor
histories containing the canonical initialization write. The rule stops at the
authenticated guarded `grantRole` boundary. Any other reachable raw `_grantRole`
call or application reference to that instance's storage withholds the absence
claim, even in dead source branches, zero-iteration loops and captured callback
bodies. This check walks owned source statements rather than the pruned CFG.
The upstream test mock deliberately exposes
delayed bootstrap and remains quiet. Modified libraries and namesakes are outside
this rule's identity scope.

This rule does not assess seed adequacy, custom libraries, arbitrary access
policies, missing initialization, or whether off-chain deployment procedures
correctly perform a deliberately exposed setup operation.

## Suppress a match

If a match is intentional, suppress it on the line before with the exact rule ID and a reason of at least eight characters:

```compact
// nightshade-disable-next-line missing-role-bootstrap -- Reason this match is intentional
```

Diagnostics cannot be suppressed, and an unmatched directive for a selected rule makes analysis incomplete. See [configuration](https://nightshade.dicksonwu.xyz/configuration.md#suppress-an-intentional-match) for fingerprint suppressions and baselines.

## References

- [Rule source document at v0.1.1](https://github.com/DicksonWu654/nightshade/blob/v0.1.1/docs/detectors/missing-role-bootstrap.md)
- [Catalog entry in rules.json](https://nightshade.dicksonwu.xyz/rules.json)
- [All rules](https://nightshade.dicksonwu.xyz/rules.md#audit-default-ordinary-rules)
- [Limitations](https://nightshade.dicksonwu.xyz/limitations.md)
