JuliusBrussee/caveman · error

postgres: unsafe runtime identity %q (session_user=%q superu

Error message

postgres: unsafe runtime identity %q (session_user=%q superuser=%t bypassrls=%t owns_tenant_table=%t)

What it means

Error "postgres: unsafe runtime identity %q (session_user=%q superuser=%t bypassrls=%t owns_tenant_table=%t)" thrown in JuliusBrussee/caveman.

Source

Thrown at shared/platform/postgresconfig/postgresconfig.go:179

		       )
		FROM pg_roles r
		WHERE r.rolname=current_user
	`, expectedRole).Scan(&currentUser, &sessionUser, &superuser, &bypassRLS, &member, &ownsTenantTable)
	if err != nil {
		return fmt.Errorf("postgres: inspect runtime identity: %w", err)
	}
	return validateRuntimeIdentity(currentUser, sessionUser, expectedRole, superuser, bypassRLS, member, ownsTenantTable)
}

func validateRuntimeIdentity(currentUser, sessionUser, expectedRole string, superuser, bypassRLS, member, ownsTenantTable bool) error {
	// A safe SET ROLE is not a safe login: session_user may execute SET ROLE
	// NONE later and recover its original privileges. Runtime pools therefore
	// require the authenticated identity and effective identity to be identical.
	if currentUser != sessionUser {
		return fmt.Errorf("postgres: runtime current_user %q differs from session_user %q", currentUser, sessionUser)
	}
	if superuser || bypassRLS || ownsTenantTable {
		return fmt.Errorf("postgres: unsafe runtime identity %q (session_user=%q superuser=%t bypassrls=%t owns_tenant_table=%t)", currentUser, sessionUser, superuser, bypassRLS, ownsTenantTable)
	}
	if !member {
		return fmt.Errorf("postgres: runtime identity %q is not a member of %q", currentUser, expectedRole)
	}
	return nil
}

type tenantTableSchema struct {
	name                   string
	nullableOrganizationID bool
	rowSecurity            bool
	forceRowSecurity       bool
	policyExists           bool
	policyPermissive       bool
	policyCommand          string
	policyAppliesToPublic  bool
	policyUsingExpression  string
	policyCheckExpression  string

View on GitHub (pinned to 27d5a3981a)

Solutions

  1. Use a non-superuser, non-BYPASSRLS runtime role that does not own the tenant table.

When it happens

Trigger: Thrown at shared/platform/postgresconfig/postgresconfig.go:179 when the library encounters an invalid state.

Common situations: See trigger scenarios.


AI-assisted analysis of JuliusBrussee/caveman@27d5a3981a (2026-08-15). Data as JSON: /api/errors/53a6799074f0accf. Report an issue: GitHub.