microsoft/semantic-kernel · error · PermissionError
Received a request from a bot with an app ID of "{app_id}".
Error message
Received a request from a bot with an app ID of "{app_id}". To enable requests from this caller, add the app ID to your configuration file. What it means
A PermissionError raised by the claims validator when an incoming skill request carries an app ID (from JWT claims) that is not in the configured ALLOWED_CALLERS set, and wildcard '*' is not configured. This is the core authorization gate: only explicitly allow-listed parent bots may invoke the skill.
Source
Thrown at python/samples/demos/copilot_studio_skill/src/api/auth.py:34
# ALLOWED_CALLERS is the setting in config.py file
# that consists of the list of parent bot ids that are allowed to access the skill
# to add a new parent bot simply go to the AllowedCallers and add
# the parent bot's microsoft app id to the list
caller_list = getattr(config, self.config_key)
if caller_list is None:
raise TypeError(f'"{self.config_key}" not found in configuration.')
self._allowed_callers = frozenset(caller_list)
@property
def claims_validator(self) -> Callable[[list[dict]], Awaitable]:
async def allow_callers_claims_validator(claims: dict[str, object]):
# if allowed_callers is None we allow all calls
if "*" not in self._allowed_callers and SkillValidation.is_skill_claim(claims):
# Check that the appId claim in the skill request is in the list of skills configured for this bot.
app_id = JwtTokenValidation.get_app_id_from_claims(claims)
if app_id not in self._allowed_callers:
raise PermissionError(
f'Received a request from a bot with an app ID of "{app_id}".'
f" To enable requests from this caller, add the app ID to your configuration file."
)
return
return allow_callers_claims_validator
View on GitHub (pinned to c028a0c7dc)
Solutions
- Add the offending app ID (shown in the message) to the ALLOWED_CALLERS env var / Config.
- Temporarily set ALLOWED_CALLERS to '*' only in trusted/dev environments to allow all (not for production).
- Verify the parent bot's app registration ID matches what was added.
Example fix
// before ALLOWED_CALLERS=11111111-2222-3333-4444-555555555555 # requesting bot is 99999999-aaaa-bbbb-cccc-dddddddddddd // after ALLOWED_CALLERS=11111111-2222-3333-4444-555555555555,99999999-aaaa-bbbb-cccc-dddddddddddd
Defensive patterns
Strategy: try-catch
Try / catch
try:
await claims_validator(claims)
except PermissionError as e:
app_id = JwtTokenValidation.get_app_id_from_claims(claims)
logger.warning("Unauthorized caller app_id=%s; add to ALLOWED_CALLERS if intended.", app_id)
raise Prevention
- Maintain ALLOWED_CALLERS as part of deployment config, updated whenever a new parent bot is onboarded.
- Use '*' only in isolated dev environments, never production.
When it happens
Trigger: A parent bot sends a skill request; SkillValidation.is_skill_claim(claims) is true; the claim's appId is not in self._allowed_callers; ALLOWED_CALLERS is not ['*'].
Common situations: A new parent bot was deployed without adding its app ID to ALLOWED_CALLERS; wrong tenant/app registration used; misconfigured allowed callers; a legitimate partner bot not yet allow-listed.
Related errors
- AllowedCallersClaimsValidator: config object cannot be None.
- "{self.config_key}" not found in configuration.
- Missing required configuration. ALLOWED_CALLERS must be set.
- No token received from token generation.
- Failed to generate token using bot_secret.
AI-assisted analysis of microsoft/semantic-kernel@c028a0c7dc (2026-08-13).
Data as JSON: /api/errors/ce98c2e40f777c2d.
Report an issue: GitHub.