# `gno.land/p/nym-moultest123/nestedpkg` Access control by package path. Instead of "is the caller this address", ask "is the caller inside my namespace, below me, or above me in the tree". ```go func IsCallerSubPath(_ int, rlm realm) bool func IsCallerParentPath(_ int, rlm realm) bool func IsSameNamespace(_ int, rlm realm) bool func AssertCallerIsSubPath(_ int, rlm realm) // panics instead func AssertCallerIsParentPath(_ int, rlm realm) func AssertIsSameNamespace(_ int, rlm realm) ``` Each helper compares `rlm.PkgPath()` with `rlm.Previous().PkgPath()`: | helper | true when the caller is | | --- | --- | | `IsCallerSubPath` | below the current realm (`r/moul/app/sub` calling `r/moul/app`) | | `IsCallerParentPath` | above it (`r/moul/app` calling `r/moul/app/sub`) | | `IsSameNamespace` | under the same `r/` prefix | That is what makes upgrade patterns work: `r/moul/app/v2` can be allowed to read `r/moul/app/v1`'s state without either version knowing the other's address, because the namespace is the credential. ## Security: why every helper takes `rlm realm` A realm value can be captured and stashed. A hostile realm that kept one from an earlier call could hand it back later to impersonate the path it names. Every helper here gates on `rlm.IsCurrent()` **first**, before reading any path, which closes that forgery: the value must be the live one for this call. The two families fail differently, on purpose: - `Is*` returns `false` on a stale `rlm` (fail closed, so a check cannot be turned into a pass by replaying an old value); - `Assert*` panics. The leading `_ int` parameter is unused (`_`). Pass `0`. --- Part of **[moul/gno-contracts](https://github.com/moul/gno-contracts)** — moul's versioned gno.land contracts. See the repository for the full catalog, build/test tooling, and usage. > ⚠️ **Disclaimer:** provided as-is, without warranty; not security-audited. Full disclaimer: [DISCLAIMER](https://github.com/moul/gno-contracts/blob/main/DISCLAIMER.md).