Attaching a service to a project
Attaching a service connects it to a project so your app can actually use it. The clever part is that The Deployer doesn't just blindly plug things together — an AI agent reads your project's code first and tells you whether the service is the right fit.
Meet the Attachment Doctor
The Attachment Doctor is an agent that inspects your project before wiring anything in. It reads your code's dependencies, configuration files (things like a database schema or settings file), and what the project appears to expect. Then it gives a verdict:
| Verdict | What it means | What you can do |
|---|---|---|
| Compatible | The service matches what your code expects | Attach it — it wires straight in |
| Wrong engine | Your code expects a different engine (e.g. it wants PostgreSQL but you picked MySQL) | Switch engines with one click, or create anyway and attach later after changing your code |
| Not needed | Your project doesn't look like it uses this kind of service | Skip it, or force the attach if you know you need it |
The agent only ever sees the names of settings, never their secret values, so your data and credentials stay private throughout.
When the verdict is wrong engine, the Doctor also gives you plain migration guidance — including a ready-to-copy prompt you can hand to a coding assistant — so you know exactly what to change.
How to attach
You can attach at two moments:
- While creating the service. On the wizard's Attach step, pick a project. The Doctor analyses it live and shows the verdict right there. If it's compatible and you continue, the service attaches automatically once it's created. See creating a service.
- Any time later. Open the service's page (Services → the service) and click Attach to a project. Pick the project, review the verdict, and confirm.
If the verdict is compatible, the service attaches. If it's wrong engine or not needed, the attach is skipped with a note and you can come back to it — nothing is forced on you silently.
What attaching actually does
When you confirm a compatible attach, The Deployer:
- Wires the connection details into your project's environment variables — the address, username, password, and so on that your app needs. These values are stored encrypted, and are the ones you'd otherwise reveal on the service page (an AWS queue or bucket is the exception: its access key belongs to your project, see below).
- Opens the network so your project's server is allowed to reach the service.
- Runs a targeted redeploy — a focused re-launch that picks up the new settings and gets your app talking to the service. You can watch it like any deployment (see launching & reading the logs).
You don't have to touch environment variables yourself, though you can view and edit them any time — see environment variables.
AWS queues and buckets: your app's own access key
An Amazon SQS queue or S3 bucket is reached with an AWS access key. When you attach one, your project gets an access key of its own in your AWS account (an IAM user named deployer-p…-app-…), allowed to use only the AWS queues and buckets attached to that project. It goes into your app's AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY. Attaching or detaching another queue or bucket changes what the key may use, never the key itself, so your running app keeps working.
- If your app already has an AWS key under those names, it is left in place, because your app may use it for other things. The service page shows kept its key next to that project.
- If your connection's AWS key isn't allowed to create IAM users, your app is given the connection's own key instead, and the attachment says which IAM permissions would let it use a key of its own (see If you limit what your connection's key may do below).
- Queues and buckets created before this give your apps the connection's own key. On the service page, Switch to scoped keys lists the projects that would change; once you confirm, each gets a key of its own and is redeployed. If an app used its old key for anything else, that stops working, so nothing switches until you confirm.
- Deleting a project deletes its key too, unless its servers may still be running (you kept them, or not all of them could be removed). Then the key is left in place and the deletion note names it.
The most a project's key can ever do
Every project key is created under a permissions boundary: an IAM policy named deployer-app-boundary in your account, which The Deployer creates the first time it needs it. Whatever the key's own policy says, the boundary caps it at sending, receiving and deleting messages on SQS queues, and reading and writing objects in S3 buckets, named deployer-svc… (the names The Deployer gives the queues and buckets it creates). It can never manage IAM, servers or anything else in your account. The policy stays in your account after projects are deleted; on its own it grants nothing. Keys made before the boundary existed are put under it the next time a queue or bucket is attached to or detached from their project, and only when that takes nothing away from your app; a key that can't be moved keeps working exactly as before.
If your account already has a policy named deployer-app-boundary that says anything other than the one below, The Deployer won't use it and won't change it: your app is given the connection's own key, as before, and the attachment tells you so.
If you limit what your connection's key may do
If your AWS connection uses an access key with AdministratorAccess, as the setup suggests, there is nothing to do. If you gave that key narrower rights on purpose, it also needs the rights below to create project keys. Without them, attaching a queue or bucket gives your app the connection's own key instead, and says so.
- Create the boundary yourself, so the connection's key never needs the right to create or change policies. In IAM, create a customer managed policy named
deployer-app-boundarywith exactly this document (replace111122223333with your account ID):
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "Queues",
"Effect": "Allow",
"Action": [
"sqs:SendMessage",
"sqs:ReceiveMessage",
"sqs:DeleteMessage",
"sqs:ChangeMessageVisibility",
"sqs:GetQueueAttributes",
"sqs:GetQueueUrl",
"sqs:PurgeQueue"
],
"Resource": "arn:aws:sqs:*:111122223333:deployer-svc*"
},
{
"Sid": "Buckets",
"Effect": "Allow",
"Action": [
"s3:ListBucket",
"s3:GetBucketLocation",
"s3:ListBucketMultipartUploads"
],
"Resource": "arn:aws:s3:::deployer-svc*"
},
{
"Sid": "Objects",
"Effect": "Allow",
"Action": [
"s3:GetObject",
"s3:PutObject",
"s3:DeleteObject",
"s3:GetObjectAcl",
"s3:PutObjectAcl",
"s3:GetObjectTagging",
"s3:PutObjectTagging",
"s3:AbortMultipartUpload",
"s3:ListMultipartUploadParts"
],
"Resource": "arn:aws:s3:::deployer-svc*/*"
}
]
}
- Give the connection's key this policy (same account ID). It may only create users named
deployer-p…-app-…, and only under that boundary, so it can never use these rights to give itself more access:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "AppKeyUsersUnderTheBoundary",
"Effect": "Allow",
"Action": [
"iam:CreateUser",
"iam:PutUserPolicy",
"iam:PutUserPermissionsBoundary"
],
"Resource": "arn:aws:iam::111122223333:user/deployer-p*-app-*",
"Condition": {
"StringEquals": {
"iam:PermissionsBoundary": "arn:aws:iam::111122223333:policy/deployer-app-boundary"
}
}
},
{
"Sid": "AppKeyUsers",
"Effect": "Allow",
"Action": [
"iam:TagUser",
"iam:DeleteUserPolicy",
"iam:CreateAccessKey",
"iam:ListAccessKeys",
"iam:DeleteAccessKey",
"iam:DeleteUser"
],
"Resource": "arn:aws:iam::111122223333:user/deployer-p*-app-*"
},
{
"Sid": "ReadTheBoundary",
"Effect": "Allow",
"Action": [
"iam:GetPolicy",
"iam:GetPolicyVersion"
],
"Resource": "arn:aws:iam::111122223333:policy/deployer-app-boundary"
}
]
}
Don't also give the connection's key iam:CreatePolicy, iam:CreatePolicyVersion, iam:SetDefaultPolicyVersion or iam:DeletePolicy on deployer-app-boundary, or iam:DeleteUserPermissionsBoundary: any of those would let it lift the cap. Then, on a queue or bucket's page, choose Switch to scoped keys to give your apps keys of their own.
Where connection details live
On the service's page, the Connection details panel shows the service's address and credentials (hidden until you click Reveal, and only available once the service is ready). The Attached projects panel lists every project using the service, with a link to the deployment that wired it in.
Detaching
To disconnect a service from a project, open the service page and click Detach next to that project. This removes exactly the environment keys that were added and runs another targeted redeploy, so your project is left clean. To remove a service entirely, detach it from every project first, then delete it — deleting tears down the underlying cloud resource so you stop being billed for it.