Adios
BlogGuide

Guide

How to Deploy an App That Uses a Private Git Dependency

A private dependency needs a credential during the build, but it does not belong in source code. A deploy key connects the repository without exposing your personal SSH key.

Adios team6 min read

When a private dependency fails in a cloud build, the code may be fine. The build simply has no safe way to prove that it can read the repository.

What the error is really saying

A local Git command can ask for a username, password, or SSH key. A remote build cannot stop and wait for that answer. When Go, npm, pip, or another tool reaches a private repository over HTTPS without a credential, Git reports that terminal prompts are disabled.

That message does not usually mean the package name is wrong. It means the build needs a non-interactive identity with permission to read the repository.

A typical private Go module failure

fatal: could not read Username for 'https://bitbucket.org': terminal prompts disabled

Use a deploy key, not your personal key

An SSH key has two halves. The public half can be registered with Bitbucket, GitHub, or GitLab. The private half proves the build owns that public key. Only the private half needs secret storage.

Create a dedicated key for this job. If the key is ever exposed, you can revoke it without breaking your personal Git access or another developer's account.

  • Give it read-only access unless the build genuinely pushes code.
  • Limit it to the repositories needed by the dependency graph.
  • Do not reuse a developer's personal SSH key.
  • Never commit either the private key or a credential-bearing repository URL.
ssh-keygen -t ed25519 -C "adios-build" -f ~/.ssh/adios-build -N ""

Put each half in the right place

Add the contents of adios-build.pub as a read-only access key on the private repository. Then upload adios-build, without the .pub suffix, to the Adios team that owns the application.

The secret name is a label you choose. The example uses BITBUCKET_DEPLOY_KEY because it makes the purpose obvious in the manifest and secret list.

cat ~/.ssh/adios-build.pub

adios secrets set BITBUCKET_DEPLOY_KEY \
  --from-file ~/.ssh/adios-build

Tell Adios and Go where private source lives

The manifest connects the build to the stored key with build.ssh. For Go projects, GOPRIVATE also tells the module tool which import paths should skip the public proxy and checksum database.

You can keep the normal HTTPS-shaped module path in go.mod. On supported Git hosts, the Adios build worker prepares SSH access for the build without adding the key to the running application.

build:
  ssh:
    - default=secret://BITBUCKET_DEPLOY_KEY
  env:
    GOPRIVATE: "bitbucket.org/your-workspace/*"

build_cmd: go build -o app ./cmd/api

Retry the build and read the next error

Run adios up again after both halves of the key and the manifest are in place. If the private dependency downloads, the connection is complete. Adios resolves the secret inside the worker and removes its temporary key file when the build ends.

If it still fails, the new message usually points to one side of the connection. Permission denied means the provider did not accept the public key. A missing secret means the private key is stored under another name or team. Go contacting its public proxy means GOPRIVATE does not cover the module's full import path.

Rotate access without changing application code

A secret reference keeps the credential out of the repository, so rotation does not require editing go.mod or source files. Create a replacement pair, authorize its public key, and update BITBUCKET_DEPLOY_KEY with adios secrets set.

Run one successful build with the replacement before removing the old public key. That short overlap avoids an unnecessary outage while still leaving one active build credential when the rotation is complete.

  All articles