Two separate bugs stacked on top of each other:
1. Buckets::servers()/accounts() used Laravel's inferred foreign key
(servers_id/accounts_id from the relation method name) instead of the
real columns (s3_server_id/s3_account_id) - pre-existing, unrelated to
backup.agent, but what this code path tripped over.
2. Even with #1 fixed, BackupAgentsService::register() read $bucket->servers
as an Eloquent relation, which runs its own query against Servers and
picks up the IAM AuthorizationScope global scope. register() is the
unauthenticated, token-only endpoint - no logged-in user, so the scope
silently filtered the result to null regardless of the FK fix.
Fixed the FK on both relations, and replaced the relation access in
register() with a direct Servers::withoutGlobalScopes()->find() lookup,
matching the pattern already used for the bucket itself two lines above.
Also resolved the endpoint-format TODO: confirmed via the panel's own
S3BucketConnectionInfo.vue that the working convention is https://{hostname},
so bucket.endpoint in the registration response is now a directly-usable URL.