Skip to content

bug(cloud): allowlist 403 is not actionable β€” client shows raw error, server never names the denied projectΒ #667

Description

@QSAS-Developer

πŸ“‹ Pre-flight Checks

  • I have searched existing issues and this is not a duplicate
  • I understand this issue needs status:approved before a PR can be opened

πŸ“ Bug Description

When a project is missing from the server's ENGRAM_CLOUD_ALLOWED_PROJECTS, the cloud rejects the push with 403 forbidden: project is not allowed. The client classifies the error correctly but then surfaces a raw transport string with no hint about what to do, and the server never names which project was denied.

The classification itself is fine β€” internal/cloud/autosync/manager.go:434-452 maps it to policy_forbidden. The problem is everything downstream:

  • internal/cloud/syncguidance/guidance.go:70 returns the message unchanged unless IsRepairableCloudSyncError(err) is true, and a 403 is not in that set (guidance.go:28-60). So no guidance is ever appended.
  • cmd/engram/cloud.go:703-729 (printCloudStatusSyncDiagnostic) prints reason_code: / reason_message: verbatim. The only Hint: in that file is line 692, for a missing token.
  • Server side, internal/cloud/cloudserver/mutations.go:255 and cloudserver.go:627,637 return the bare string forbidden: project is not allowed without naming the project or the allowlist variable.

The result is an error that tells you something is forbidden but not what, not why, and not how to fix it. Neither ENGRAM_CLOUD_ALLOWED_PROJECTS nor engram cloud enroll <project> is mentioned anywhere in the output.

πŸ”„ Steps to Reproduce

  1. Run a cloud server whose ENGRAM_CLOUD_ALLOWED_PROJECTS omits at least one project that exists locally.
  2. Enroll that project on the client: engram cloud enroll <project> β€” this succeeds, because enrollment is client-side only.
  3. engram cloud upgrade bootstrap --project <project>

βœ… Expected Behavior

The client should say which project was denied and point at the fix, e.g.:

engram: bootstrap first push: cloud: fetch manifest: status 403: forbidden: project "acme-crm" is not allowed
Hint: the cloud server's ENGRAM_CLOUD_ALLOWED_PROJECTS does not include "acme-crm".
      Add it to /etc/engram/engram.env on the server and restart the service.

And engram cloud status should render the same hint alongside reason_code: policy_forbidden.

❌ Actual Behavior

engram: bootstrap first push: cloud: fetch manifest: status 403: forbidden: project is not allowed

That is the whole output. Nothing indicates the allowlist is the mechanism, nor which project tripped it. With several projects to bootstrap, you cannot tell from the error which ones are affected β€” you have to bisect by running them one at a time.

The client-side enroll succeeding beforehand actively misleads: it looks like the project is authorised.

Operating System

Linux (Ubuntu/Debian)

Engram Version

1.20.0

Agent / Client

Claude Code

πŸ“‹ Relevant Logs

$ engram cloud enroll acme-crm
βœ“ Project "acme-crm" enrolled for cloud sync

$ engram cloud upgrade bootstrap --project acme-crm
engram: bootstrap first push: cloud: fetch manifest: status 403: forbidden: project is not allowed

πŸ’‘ Additional Context

Suggested fix, small and contained:

  1. Add a policy_forbidden branch to the guidance path (internal/cloud/syncguidance), or a Hint: line in cmd/engram/cloud.go:720-728, naming the project and ENGRAM_CLOUD_ALLOWED_PROJECTS.
  2. Include the denied project name in the server's 403 body (internal/cloud/cloudserver/mutations.go:255).

Happy to open a PR for this once it has status:approved β€” it looks like a clean, low-risk change.

Context on how this was hit: while repairing a broken cloud sync, four projects out of twenty-three failed bootstrap with this error and there was no way to tell from the message that a server-side allowlist was involved. Reading the server config was the only way to find out.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions