Tencent/WeKnora · error
storage path is outside KB-scoped exports namespace
Error message
storage path is outside KB-scoped exports namespace
What it means
Authorization guard in ValidateKBScopedStoragePath (presign.go): the storage path passes tenant ownership checks but is not under the exports/ namespace used for KB-embedded images. This blocks borrowers with shared-KB read access from proxying arbitrary owner-tenant objects such as raw knowledge uploads.
Source
Thrown at internal/utils/presign.go:136
return fmt.Errorf("storage path has no tenant segment")
}
if pathTenant != tenantID {
return fmt.Errorf("storage path workspace mismatch")
}
return nil
}
// ValidateKBScopedStoragePath is used by GET /knowledge-bases/:id/files. It
// requires the path to belong to the KB owner tenant and to live under the
// exports/ namespace used for embedded images (SaveBytes / multimodal output).
// This prevents borrowers with shared-KB read access from using the proxy to
// fetch arbitrary owner-tenant objects such as raw knowledge uploads.
func ValidateKBScopedStoragePath(filePath string, tenantID uint64) error {
if err := ValidateStoragePathTenant(filePath, tenantID); err != nil {
return err
}
if !storagePathHasExportsScope(filePath, tenantID) {
return fmt.Errorf("storage path is outside KB-scoped exports namespace")
}
return nil
}
// storageBackendScheme wraps a provider:// path with the concrete instance id:
// storage://<backendID>/<provider>://... It is duplicated here (rather than
// reusing types.ParseStorageBackendPath) because internal/types already imports
// internal/utils, so a reverse import would create a cycle.
const storageBackendScheme = "storage://"
// unwrapStorageBackendPath strips a leading storage://<backendID>/ wrapper and
// returns the inner provider:// path. Non-wrapped paths are returned unchanged.
// This keeps tenant/exports parsing anchored on the provider path instead of
// relying on the backend id happening not to look like a tenant segment.
func unwrapStorageBackendPath(filePath string) string {
if !strings.HasPrefix(filePath, storageBackendScheme) {
return filePath
}View on GitHub (pinned to 988cbb0330)
Solutions
- Only presign paths under the KB exports/ namespace
- Serve other object types through dedicated, permission-checked endpoints
- Treat attempts to reach non-export paths as an access violation
Defensive patterns
Strategy: validation
When it happens
Trigger: Thrown at internal/utils/presign.go:136 when the library encounters an invalid state.
Common situations: See trigger scenarios.
AI-assisted analysis of Tencent/WeKnora@988cbb0330 (2026-09-02).
Data as JSON: /api/errors/b357caa82ef97c17.
Report an issue: GitHub.