Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,20 @@ hosted within CodeArtifact. It will use any appropriate AWS credentials provided
--index-url https://${DOMAIN}-${ACCOUNT}.d.codeartifact.${REGION}.amazonaws.com/pypi/${REPOSITORY}/simple/
```

### Environment Variable

You can bypass AWS API calls by setting the `CODEARTIFACT_AUTH_TOKEN` environment variable:

```bash
# Set the environment variable with a valid token
export CODEARTIFACT_AUTH_TOKEN=your-auth-token-here

# Then use pip/twine as usual, and the token will be used automatically
pip install package-name --index-url https://${DOMAIN}-${ACCOUNT}.d.codeartifact.${REGION}.amazonaws.com/pypi/${REPOSITORY}/simple/
```

This is especially useful in CI/CD environments or when you want to avoid making AWS API calls.

Config
------
This backend provides a number of configuration options to modify the behaviour of the AWS client.
Expand Down
16 changes: 16 additions & 0 deletions keyrings/codeartifact.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
# codeartifact.py -- keyring backend

import os
import re
import logging

Expand Down Expand Up @@ -144,6 +145,21 @@ def get_credential(self, service, username):
return credentials.SimpleCredential("aws", authorization_token)

def get_password(self, service, username):

# Get the environment variable name from config defaults (if provided),
# otherwise fall back to the standard CODEARTIFACT_AUTH_TOKEN.
# Note: self.config is a CodeArtifactKeyringConfig, not a dict.
env_variable_name = (
getattr(self.config, "defaults", {})
.get("env_variable", "CODEARTIFACT_AUTH_TOKEN")
)

# Check for token in environment variable
token_from_env = os.getenv(env_variable_name)
if token_from_env:
logging.info(f"Using token from environment variable: {env_variable_name}")
return token_from_env

url = urlparse(service)

# Do a quick check to see if this service URL applies to us.
Expand Down
22 changes: 21 additions & 1 deletion tests/test_backend.py
Original file line number Diff line number Diff line change
Expand Up @@ -170,4 +170,24 @@ def make_client(options):
config = CodeArtifactKeyringConfig(config_file=config_file.name)
backend = CodeArtifactBackend(config=config, make_client=make_client)
url = codeartifact_pypi_url("domain", "000000000000", "region", "name")
credentials = backend.get_credential(url, None)
backend.get_credential(url, None)


def test_get_credential_from_env(monkeypatch):
"""
Tests that the backend can retrieve a token from an environment variable.
"""
monkeypatch.setenv("CODEARTIFACT_AUTH_TOKEN", "ENV_TOKEN")

def make_client(options):
# This should not be called when token is in env
pytest.fail("make_client should not be called when token is in env")

config = CodeArtifactKeyringConfig(config_file=StringIO())
backend = CodeArtifactBackend(config=config, make_client=make_client)

url = codeartifact_pypi_url("domain", "000000000000", "region", "name")
credentials = backend.get_credential(url, None)

assert credentials.username == "aws"
assert credentials.password == "ENV_TOKEN"