{"record":{"id":"cdbe7a477692e347","repo":"iflytek/astron-agent","slug":"exceed-authority","errorCode":"EXCEED_AUTHORITY","errorMessage":"BusinessException(ResponseEnum.EXCEED_AUTHORITY)","messagePattern":"BusinessException\\(ResponseEnum\\.EXCEED_AUTHORITY\\)","errorType":"error_code","errorClass":"BusinessException","httpStatus":null,"severity":"error","filePath":"console/backend/toolkit/src/main/java/com/iflytek/astron/console/toolkit/service/model/LLMService.java","lineNumber":553,"sourceCode":"                        .fluentPut(\"patchId\", patchId));\n            }\n        });\n\n        return array;\n    }\n\n    public Object selfModelConfig(Long id, Integer llmSource) {\n        if (llmSource != 0) {\n            throw new BusinessException(ResponseEnum.NOT_CUSTOM_MODEL);\n        }\n        String uid = UserInfoManagerHandler.getUserId();\n\n        Model one = modelMapper.selectOne(new LambdaQueryWrapper<Model>().eq(Model::getId, id));\n        if (one == null) {\n            throw new BusinessException(ResponseEnum.MODEL_NOT_EXIST);\n        }\n        if (!Objects.equals(uid, one.getUid())) {\n            throw new BusinessException(ResponseEnum.EXCEED_AUTHORITY);\n        }\n        List<Config> configs = JSON.parseArray(one.getConfig(), Config.class);\n        if (CollUtil.isNotEmpty(configs)) {\n            for (Config config : configs) {\n                Float precision = config.getPrecision();\n                if (precision != null) {\n                    // If precision is an integer greater than 1, convert to decimal form, e.g., 1 to 0.1, 2 to 0.01,\n                    // etc.\n                    int intPrec = Math.round(precision);\n                    if (precision >= 1 && Math.abs(precision - intPrec) < 1e-6) {\n                        float newPrec = 1f / (float) Math.pow(10, intPrec);\n                        config.setPrecision(newPrec);\n                    }\n                }\n            }\n        }\n        return ApiResult.success(configs);\n    }","sourceCodeStart":535,"sourceCodeEnd":571,"githubUrl":"https://github.com/iflytek/astron-agent/blob/5e758547a83371a5a4b29dadf4ac03e8dd527635/console/backend/toolkit/src/main/java/com/iflytek/astron/console/toolkit/service/model/LLMService.java#L535-L571","documentation":"selfModelConfig verifies that the current user (from UserInfoManagerHandler) owns the model row. If the stored uid differs from the caller's uid, it throws BusinessException(EXCEED_AUTHORITY): the user is attempting to read/modify another user's custom model configuration.","triggerScenarios":"Authenticated user A requests self-model config for a model id owned by user B. Also occurs when the auth context is missing/misresolved so uid resolves to a different (or empty) identity than the model owner.","commonSituations":"Sharing model ids across accounts/spaces; broken auth header so userId resolves incorrectly; admin tooling acting without impersonation; id guessed/enumerated by a client.","solutions":["Confirm the caller owns the model id before calling the endpoint","Check the auth token/session is valid and resolves to the expected userId","Do not reuse model ids from other users or spaces in clients","If admin access is needed, add an explicit admin path rather than bypassing ownership"],"exampleFix":null,"handlingStrategy":"validation","validationCode":"// ownership check before calling\nModel m = modelMapper.selectById(id);\nif (m == null || !Objects.equals(currentUserId, m.getUid())) {\n    throw new SecurityException(\"model \" + id + \" is not owned by the current user\");\n}","typeGuard":null,"tryCatchPattern":"try {\n    llmService.selfModelConfig(id, 0);\n} catch (BusinessException e) {\n    // EXCEED_AUTHORITY: return 403-style response, do not retry\n}","preventionTips":["Scope model queries by current user/space so foreign ids 404","Ensure auth middleware reliably resolves userId","Never accept arbitrary model ids without ownership checks","Log ownership violations for security review"],"tags":["authorization","ownership","llm","java"],"backgroundTag":"permission-denied","analyzedSha":"5e758547a83371a5a4b29dadf4ac03e8dd527635","analyzedAt":"2026-09-12T08:03:51.356Z","contentChangedAt":"2026-09-12T08:03:51.356Z","schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}