infiniflow/ragflow · error · LookupError
Tenant {tenant_id} has no access to provider owned by tenant
Error message
Tenant {tenant_id} has no access to provider owned by tenant {provider_obj.tenant_id}. What it means
LookupError raised by get_api_key (direct-ID path) as a tenant-access guard: the model's provider is owned by provider_obj.tenant_id, and the requesting tenant_id is neither the owner nor one of its joined teams (checked via TenantService.get_joined_tenants_by_user_id). It prevents a tenant from extracting another tenant's API key through a guessed or shared model id.
Source
Thrown at api/db/joint_services/tenant_model_service.py:449
params[id_field] = resolve_model_id(tenant_id, model_type, params[name_field])
except LookupError:
logger.debug("Could not resolve %s → %s for tenant %s, skipping", name_field, id_field, tenant_id)
return params
def get_api_key(tenant_id: str, model_name: str):
# Try direct model ID (UUID) lookup first
exist, model_obj = TenantModelService.get_by_id(model_name)
if exist:
# Verify tenant ownership through the provider chain
ok, provider_obj = TenantModelProviderService.get_by_id(model_obj.provider_id)
if not ok:
raise LookupError(f"Provider id={model_obj.provider_id} not found for model {model_name}.")
if tenant_id != provider_obj.tenant_id:
joined_tenants = TenantService.get_joined_tenants_by_user_id(tenant_id)
joined_tenant_ids = [t["tenant_id"] for t in joined_tenants]
if provider_obj.tenant_id not in joined_tenant_ids:
raise LookupError(f"Tenant {tenant_id} has no access to provider owned by tenant {provider_obj.tenant_id}.")
exist_inst, instance_obj = TenantModelInstanceService.get_by_id(model_obj.instance_id)
if not exist_inst:
logger.warning(
"Direct-ID resolution: instance not found | tenant_id=%s model_id=%s instance_id=%s",
tenant_id,
model_name,
model_obj.instance_id,
)
raise LookupError(f"Instance {model_obj.instance_id} not found for model {model_name}.")
logger.debug(
"Direct-ID resolution: resolved | tenant_id=%s model_id=%s instance_id=%s",
tenant_id,
model_name,
model_obj.instance_id,
)
return instance_obj.api_key
View on GitHub (pinned to 554fb1133a)
Solutions
- Use a model id (or model@provider name) that belongs to the authenticated tenant.
- If sharing is intended, have the consumer tenant join the provider owner's team so get_joined_tenants_by_user_id includes the owner.
- Or add the same provider under the consuming tenant with its own key and reference that tenant's model.
- Never hardcode cross-tenant ids; resolve names per tenant at runtime.
Defensive patterns
Strategy: try-catch
Validate before calling
exist, m = TenantModelService.get_by_id(model_id)
if exist:
_, p = TenantModelProviderService.get_by_id(m.provider_id)
if tenant_id != p.tenant_id:
joined = {t["tenant_id"] for t in TenantService.get_joined_tenants_by_user_id(tenant_id)}
if p.tenant_id not in joined:
raise PermissionError("Model belongs to another tenant") Try / catch
try:
key = get_api_key(tenant_id, model_id)
except LookupError as e:
if "has no access" in str(e):
# authorization failure: stop, do not retry with same credentials
raise PermissionError(str(e)) Prevention
- Resolve model references per tenant at runtime; never hardcode another tenant's ids.
- For team sharing, join the owner's team first so joined-tenant checks pass.
- Treat this error as a security signal — audit where the foreign id came from.
When it happens
Trigger: Passing a model id owned by tenant A while authenticating as tenant B, where B has not joined a team of A's; typical when ids are copied between accounts or an integration hardcodes one tenant's model id.
Common situations: Multi-tenant deployments where a user pastes a colleague's model id; SDK scripts reusing a recorded id after switching login; misconfigured tenant scoping in a proxy.
Related errors
- Instance {model_obj.instance_id} not found for model {model_
- Provider name is required.
- Provider {provider_name} not found.
- main() must return a value. Use null for an empty result.
- message.compileNotSupported
AI-assisted analysis of infiniflow/ragflow@554fb1133a (2026-08-15).
Data as JSON: /api/errors/1f1fdf9621c52d01.
Report an issue: GitHub.