• …p+CAS, tenant enforcement
    
    Audit findings 1-5 confirmed real; root causes were (a) identity self-reported by
    the client, (b) every failure path defaulting open.
    
    - ERP /ai/whoami (saas-8s+ @c8e0057 follow-up) resolves token → real user/tenant/type;
      AuthzService.resolveIdentity is now the single identity entry point. Client-supplied
      userid/brandsid/usertype removed from all request bodies and from chat.html.
    - dev-login is a real switch (erp.dev-login.enabled, default false) and its ERP creds
      no longer have built-in admin/666666 defaults; blank token in production → 401,
      never a silent fall back to the dev (sysadmin) account.
    - conversations/op/form endpoints require login; conversation ids are namespaced by
      user id and ownership-checked (403 otherwise); /op/pending no longer returns sPayload.
    - op confirm/cancel check the proposer, and confirm claims the draft via CAS so
      concurrent/repeat confirms cannot execute twice; bill numbers are regenerated at
      execution time instead of replaying the propose-time snapshot.
    - FK options take the tenant from the introspected identity and return empty rather
      than dropping the sBrandsId predicate.
    - secrets moved to env vars (DB_URL/DB_USERNAME/DB_PASSWORD/REDIS_*/LLM_*/ERP_BASEURL);
      allowMultiQueries=false. NOTE: the previously committed credentials must be rotated.
    - ids interpolated into ERP URLs are validated (safeId) to stop query/path injection.
    - update path rejects system columns, resolves FK names, and coerces by column type;
      numeric coercion now rejects unparseable input instead of writing 0/truncating, and
      proposal summaries show the value that will actually be written.
    - ResponseStatusException keeps its 401/403 status instead of being wrapped as 200.
    - anti-fabrication guard stays on when the intent gate itself fails.
    zichun authored
     
    Browse Code »


  • …ormCollect + Skills + KgSearch
    
    - AgentIdentity + AgentFactory: build agent per request with token+form-allowlist carried in tool instances (per-call context; robust vs LC4j callback threading)
    - ErpClient: token-aware read/write/examine; user-token expiry does NOT silently re-login as dev-admin (no privilege escalation)
    - AuthzService: devIdentity()/userIdentity() resolve granted-form set (sAuthsId)
    - proposeExamine tool + OpController examine dispatch + forward user Authorization on confirm
    - InteractionTool.askUser (structured options), FormCollectTool.collectForm (real gdsconfigformslave schema)
    - SkillService + SkillTool.loadSkill + ai_skill digest in system prompt
    - KgQueryTool.kgSearch: L2 neighbors/flow + L3 field->table
    - tools ErpReadTool/ProposeWriteTool/QueryTool/FormCollectTool now per-request (not @Component)
    zichun authored
     
    Browse File »
  • - AuthzService: form-level allowlist ported from backend getsAuthsIdNew (sysjurisdiction sKey set); sysadmin=all; wired into Read/lookupRecord/proposeUpdate/proposeDelete (admin dev-login => all-access; enforces per-user once prod passes through user token)
    - proposeDelete + ErpClient.deleteForm (handleType=del) + OpController branches op type; HITL-gated like update
    - docs/security-findings.md: report of the 5 current-system vulns (backend form-perm off, read-API-can-write, NL2SQL no-tenant/over-privilege/partial-SQL-safety/cache-skips-validation) for the business
    - Verified end-to-end: read after authz = 93; propose-delete card -> confirm -> row actually deleted; audit rows written.
    zichun authored
     
    Browse File »