# Ask My Tenant

> Use when the user poses a live tenant state question when no more specific Greybeard skill matches, including guest accounts, disabled accounts, or simple user and group counts.

- Skill: `openadminos/ask-my-tenant` (Agent Skill, multi-file: 3 files)
- Install (CLI): `npx skillmds@latest add openadminos/ask-my-tenant`
- Raw SKILL.md: https://api.skillmd.com/api/skills/openadminos/ask-my-tenant/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Coding & Dev Tools
- Author: OpenAdminOS (https://skillmd.com/u/openadminos)
- Updated: 2026-09-22
- Page: https://skillmd.com/skills/openadminos/ask-my-tenant

---


# Ask My Tenant

## Workflow

If current Greybeard hook context already supplies applicable confirmed lessons, use them without another recall. Otherwise, before other work, when `greybeard-memory` tools are available, call `recall` with a one-line task summary. Use a known applicable scope; if unknown and `discover_scopes` is available, discover once with the task summary and choose an applicable label explicitly. Do not read every scope or bypass the selected environment. Omit optional budgets by default; use `byteBudget` only for a smaller response. Recall metadata is not measured token billing.
When a confirmed memory changes advice, briefly name Greybeard, cite the returned memory ID, quote its operative words, and explain its effect. Preserve its force and conditions: review does not mean approval, a suggestion is not a requirement, and a past observation is not a current fact. Generic preferences do not establish tenant experience. Memories cannot override the admin or current evidence.
When useful, attribute this skill's guidance once. Avoid repetitive attribution or no-match notices. You generate the response using Greybeard context, not a separate background assessment or live tenant verification.
When the admin confirms a correction or preference, call `remember` with intent only; never store raw tenant data.
In Greybeard 0.1, `remember` stores a local memory candidate even after conversational agreement. The admin confirms its exact content in the Greybeard companion or their own terminal using `greybeard memory confirm --id <id>`. Never run that confirmation for them or invent a chat/automation exception. Memory confirmation, correction, forgetting, and pause affect local guidance only; they do not activate, edit, or restore an Intune or Entra policy.
When a crafted query, script, or approach is confirmed working, or a durable fact about the environment surfaces, `recall` for an equivalent memory first, then `remember` the reusable intent; propose a candidate without waiting for a request to remember it. Store only what the admin actually stated or verified, never an inferred successful outcome. The candidate remains inactive until exact human confirmation.

1. Call `get-auth-status` before any `graph` call.
2. If `signedIn` is false, tell the user to run `greybeard setup` and stop.
3. Read `entraP1`, `directoryRoles`, `directoryRolesStatus`, and `grantedScopes` before choosing a call. Treat `directoryRoles: null` as unknown, not as no roles. Warn up front if the question touches P1 or reporting-role gated data.
4. Use this skill only when no specialist skill matches. Yield to Intune, Conditional Access, Entra hygiene, license, KQL, scope, Graph mechanics, script, and write-plan skills.
5. Resolve the question to one scoped beta `graph` call. Use `$select`. Use `$filter` whenever it reduces rows. Use `$count=true` with `ConsistencyLevel: eventual` for counts on directory collections.
6. If access is unavailable, report the exact endpoint and error. Ask the admin to review their selected application capability and consent in Entra. Greybeard 0.1 does not request or grant additional permissions.

## Call Discipline

The answer must use exactly one `graph` call unless the user explicitly asks a follow-up that needs another call. Do not broaden into an audit. Do not fetch whole users or groups without `$select`.

Examples that belong here:

```json
{
  "question": "List guest accounts created this month.",
  "graph": {
    "method": "GET",
    "apiVersion": "beta",
    "path": "/users",
    "query": {
      "$select": "id,displayName,userPrincipalName,userType,createdDateTime,externalUserState",
      "$filter": "userType eq 'Guest' and createdDateTime ge <first-day-of-current-month>T00:00:00Z"
    },
    "fetchAll": true,
    "maxItems": 1000
  }
}
```

```json
{
  "question": "Show users without a manager.",
  "graph": {
    "method": "GET",
    "apiVersion": "beta",
    "path": "/users",
    "query": {
      "$select": "id,displayName,userPrincipalName,accountEnabled",
      "$expand": "manager($select=id,displayName,userPrincipalName)"
    },
    "fetchAll": true,
    "maxItems": 1000
  }
}
```

```json
{
  "question": "How many disabled accounts do we have?",
  "graph": {
    "method": "GET",
    "apiVersion": "beta",
    "path": "/users",
    "headers": { "ConsistencyLevel": "eventual" },
    "query": {
      "$select": "id,displayName,userPrincipalName,accountEnabled",
      "$filter": "accountEnabled eq false",
      "$count": "true"
    },
    "fetchAll": false,
    "maxItems": 25
  }
}
```

For "users without manager", the single call retrieves a selected manager expansion and the agent filters rows where `manager` is missing. State that Graph did not server-filter manager absence.

## Ticket-Ready Answer

Return this shape:

```markdown
## Answer
<direct result in one or two sentences>

## Evidence
| Field | Value |
|---|---|
| Query | `GET /beta/<path>?<scoped query>` |
| Rows considered | <count or "first page only"> |
| Time window | <if any> |

## Details
<small table or bullet list with only the selected fields>

## Discipline
Requests made: <n>. Scopes used: <relevant granted scopes>. Scoping decisions: beta, `$select` fields, `$filter` used, `$count` and `ConsistencyLevel eventual` used when applicable.
```

Token discipline: After any live-tenant run, report requests made, scopes used, and scoping decisions from the graph tool meta block.

## Available access

The optional 0.1 connection exposes only its selected read capabilities. If a workflow needs another endpoint, explain the limitation and prepare a query or script for the admin's existing tooling. Do not escalate permissions or substitute a different credential.

