Skip to content
Merged
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
2 changes: 1 addition & 1 deletion .github/workflows/gem-build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ jobs:
runs-on: ubuntu-latest
strategy:
matrix:
ruby-version: ['3.3', '3.4']
ruby-version: ['4.0']

steps:
- uses: actions/checkout@v4
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/gem-push.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ jobs:
runs-on: ubuntu-latest
strategy:
matrix:
ruby-version: ['3.3', '3.4' ]
ruby-version: ['4.0']

steps:
- uses: actions/checkout@v2
Expand All @@ -33,7 +33,7 @@ jobs:
- name: Set up Ruby 3.4.2
uses: ruby/setup-ruby@v1
with:
ruby-version: 3.4.2
ruby-version: 4.0.2
bundler-cache: true

- name: Publish to RubyGems
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/gem-test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ jobs:
runs-on: ubuntu-latest
strategy:
matrix:
ruby-version: ['3.3', '3.4' ]
ruby-version: ['4.0']

steps:
- uses: actions/checkout@v2
Expand Down
2 changes: 1 addition & 1 deletion .rubocop.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ inherit_gem:
dvla-lint: ".rubocop.yml"

AllCops:
TargetRubyVersion: 3.0
TargetRubyVersion: 4.0

Style/StringLiterals:
EnforcedStyle: single_quotes
Expand Down
2 changes: 1 addition & 1 deletion .ruby-version
Original file line number Diff line number Diff line change
@@ -1 +1 @@
3.4.7
4.0.2
2 changes: 1 addition & 1 deletion .tool-versions
Original file line number Diff line number Diff line change
@@ -1 +1 @@
ruby 3.4.7
ruby 4.0.2
13 changes: 9 additions & 4 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,14 +1,19 @@
## [Unreleased]

## [1.0.2] - 2024-11-07
## [1.0.5] - 2025-11-10

- Initial release
- Fixed AWS credential handling to return proper credentials from assume role
- Added AWS credential chain and SSO documentation to README

## [1.0.4] - 2025-11-10

- Update gems and fixed issue with git actions

## [1.0.3] - 2025-09-03

- Moved runtime dependencies to the gemspec

## [1.0.4] - 2025-11-10
## [1.0.2] - 2024-11-07

- Update gems and fixed issue with git actions
- Initial release

6 changes: 3 additions & 3 deletions Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,11 @@ source 'https://rubygems.org'
# Specify your gem's dependencies in dvla-kaping.gemspec
gemspec

gem 'bundler-audit', '~> 0.9.2'
gem 'dvla-lint', '~> 1.8'
gem 'bundler-audit', '~> 0.9.3'
gem 'dvla-lint', '~> 1.10'
gem 'rake', '~> 13.0'
gem 'rspec', '~> 3.0'
gem 'rspec-sonarqube-formatter', '~> 1.5'
gem 'rubocop', require: false
gem 'rubocop', '~> 1.86', require: false
gem 'simplecov', '~> 0.22'
gem 'simplecov-console', '~> 0.9'
44 changes: 39 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -74,18 +74,52 @@ kaping:

```
If you want to use the built-in client, and your OpenSearch instance is hosted in a Amazon VPC you will need to assume AWS permissions for access to run the queries.
there are two options, you can either use profile or environment
There are two options, you can either use profile or environment

Profile will just pick up the credentials save in your specified shared credentials ini file at ~/.aws/credentials,
Profile will just pick up the credentials saved in your specified shared credentials ini file at ~/.aws/credentials,

```yml
aws:
# to use an AWS profile config file then set to profile, otherwise environment settings will be used
credential_type: profile
# to use an AWS profile config file, then set to profile, otherwise environment settings will be used
credential_type: profile | env | credentials
account_id: ##########
role: ROLE
region: aws-region
profile: PROFILE
role: ROLE

```

### AWS Credential Chain

The gem supports three credential strategies:

| credential_type | How it works |
|---|---|
| `profile` | Uses the named profile from `~/.aws/config` to create an STS client, then assumes the configured role. Supports SSO profiles. |
| `env` | Uses environment variables (`AWS_ACCESS_KEY_ID`, `AWS_SECRET_ACCESS_KEY`, or `AWS_PROFILE`) to create an STS client, then assumes the configured role. |
| `credentials` | Delegates to the AWS SDK default credential provider chain, which walks through env vars → shared config/credentials → SSO → ECS/EC2 instance roles in order. No role assumption is performed. |

### Using AWS SSO

If your organisation uses AWS IAM Identity Center (SSO), authenticate first then set the profile:

```bash
aws sso login --profile my-sso-profile
```

Then either:
- Set `credential_type: profile` and `profile: my-sso-profile` in your `kaping.yml`
- Or set `credential_type: env` / `credentials` and export `AWS_PROFILE=my-sso-profile`

The SDK will resolve the cached SSO token automatically. Ensure your `~/.aws/config` has the SSO profile configured, for example:

```ini
[profile my-sso-profile]
sso_start_url = https://my-org.awsapps.com/start
sso_region = eu-west-2
sso_account_id = 123456789012
sso_role_name = MyRole
region = eu-west-2
```

## Client
Expand Down
8 changes: 4 additions & 4 deletions dvla-kaping.gemspec
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ Gem::Specification.new do |spec|
spec.summary = 'Idiomatic way to create DSL openSearch definitions'
spec.description = 'Wrapper for the AWS elastic search API to create an idiomatic way to build complex search queries'
spec.homepage = 'https://github.com/dvla/kaping'
spec.required_ruby_version = '>= 3'
spec.required_ruby_version = '>= 4'
spec.license = 'MIT'

spec.metadata['homepage_uri'] = spec.homepage
Expand All @@ -34,7 +34,7 @@ Gem::Specification.new do |spec|
spec.require_paths = %w[lib]

spec.add_dependency 'aws-sdk-sts', '~> 1.12'
spec.add_dependency 'aws-sigv4', '~> 1.8'
spec.add_dependency 'nokogiri', '~> 1.18', '>= 1.18.8'
spec.add_dependency 'opensearch-aws-sigv4', '~> 1.2', '>= 1.2.1'
spec.add_dependency 'aws-sigv4', '~> 1.12'
spec.add_dependency 'nokogiri', '~> 1.19'
spec.add_dependency 'opensearch-aws-sigv4', '~> 1.3'
end
37 changes: 25 additions & 12 deletions lib/dvla/kaping/aws_client.rb
Original file line number Diff line number Diff line change
Expand Up @@ -11,25 +11,34 @@ def initialize
@base_url = Kaping.yaml[:kaping_host]
@aws_account_id = Kaping.yaml.dig(:aws, :account_id)
@role = Kaping.yaml.dig(:aws, :role)
@region = Kaping.yaml.dig(:aws, :region)
Kaping.logger.info { "Kaping Client | base_url: '#{@base_url}'" }
@region = Kaping.yaml.dig(:aws, :region) || 'eu-west-2'
Kaping.logger.debug { "AWS Client | base_url: '#{@base_url}'" }
end

def select_credentials
case Kaping.yaml.dig(:aws, :credential_type)
when 'profile'
assume_role_profile(@aws_account_id, @role)
when 'env'
assume_role_env(@aws_account_id, @role)
when 'credentials'
Aws::CredentialProviderChain.new.resolve
else
logger.warn { 'Credential type not recognised, please set an option: profile, env or credentials' }
end
end

def connect
credentials = if Kaping.yaml.dig(:aws, :credential_type) == 'profile'
assume_role_profile(@aws_account_id, @role)
else
assume_role_env(@aws_account_id, @role)
end
credentials = select_credentials

signer = Aws::Sigv4::Signer.new(service: 'es',
region: @region,
credentials_provider: credentials)

OpenSearch::Aws::Sigv4Client.new({
host: @base_url,
log: false,
}, signer)
host: @base_url,
log: false,
}, signer)
end

private
Expand All @@ -38,7 +47,9 @@ def connect
def assume_role_profile(aws_account_id, role)
role_arn = "arn:aws:iam::#{aws_account_id}:role/#{role}"
sts = Aws::STS::Client.new(region: @region, profile: Kaping.yaml.dig(:aws, :profile))
sts.assume_role(role_arn: role_arn, role_session_name: 'kaping')
resp = sts.assume_role(role_arn: role_arn, role_session_name: 'kaping')
Aws::Credentials.new(resp.credentials.access_key_id, resp.credentials.secret_access_key,
resp.credentials.session_token)
rescue Aws::STS::Errors::ServiceError => e
raise "#{__method__}: AWS Profile Credentials Issue: #{e.message} #{e.class.name}"
end
Expand All @@ -47,7 +58,9 @@ def assume_role_profile(aws_account_id, role)
def assume_role_env(aws_account_id, role)
role_arn = "arn:aws:iam::#{aws_account_id}:role/#{role}"
sts = Aws::STS::Client.new(region: @region)
sts.assume_role(role_arn: role_arn, role_session_name: 'kaping')
resp = sts.assume_role(role_arn: role_arn, role_session_name: 'kaping')
Aws::Credentials.new(resp.credentials.access_key_id, resp.credentials.secret_access_key,
resp.credentials.session_token)
rescue Aws::STS::Errors::ServiceError => e
raise "#{__method__}: AWS ENV Credentials Issue: #{e.message} #{e.class.name}"
end
Expand Down
2 changes: 1 addition & 1 deletion lib/dvla/kaping/version.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,6 @@

module DVLA
module Kaping
VERSION = '1.0.4'
VERSION = '1.0.5'
end
end
Loading