Add IAM role column for Bedrock self-hosted models
What does this merge request do and why?
- What? Adds the
iam_rolecolumn for model selection entries. - Why? To introduce support for passing an assumable IAM role to AI Gateway via model metadata.
🤖 Claude summary
Adds an optional iam_role column to GitLab Duo Self-Hosted models so an administrator can name an IAM role for AI Gateway to assume through STS when it reaches Amazon Bedrock. The value is validated as an IAM role ARN, is only accepted for Bedrock, and is sent to AI Gateway as iam_role in the model metadata. It is left out of the metadata when blank.
This is layer 1 of 3. The original MR was split because it was large and mixed GraphQL backend and frontend changes:
- This MR: migrations, model validation and metadata.
- !259628 (merged): GraphQL, docs and the instance ID for the form.
- !259629 (merged): the admin form field.
Not included
- STS ExternalId: Rails does not send one. AI Gateway derives it from the authenticated instance identity (the JWT claims or the instance ID header) so a caller cannot choose it. That change is in gitlab-org/modelops/applied-ml/code-suggestions/ai-assist!7210 (merged).
- Code completion: the IAM role is sent for the metadata path used by chat and flows (
model_metadata_params). The code completion request builders (CodeSuggestions::Prompts::CodeCompletion::AiGatewayCodeCompletionMessageandAi::FeatureSetting#model_request_params) do not carry it yet and are left for a follow-up.
References
- Companion AI Gateway MR: gitlab-org/modelops/applied-ml/code-suggestions/ai-assist!7210 (merged)
Database
One migration, 20261001090000, adds ai_self_hosted_models.iam_role (text) with with_lock_retries and if_not_exists: true, then calls add_text_limit (2048, the maximum IAM role ARN length).
db:gitlabcom-database-testing passed (5.5 s, +0.00 B): !259000 (comment 3958500930). The commits after it only changed the model and specs, so the results still hold and a re-run isn't needed.
Migration output (run against the local Caproni database):
db:migrate:down
$ VERSION=20261001090000 bundle exec rake db:migrate:down
main: == 20261001090000 AddIamRoleToAiSelfHostedModels: reverting ===================
main: -- transaction_open?(nil)
main: -> 0.0000s
main: -- remove_column(:ai_self_hosted_models, :iam_role, {:if_exists=>true})
main: -> 0.0498s
main: == 20261001090000 AddIamRoleToAiSelfHostedModels: reverted (0.0744s) ==========db:migrate:up
$ VERSION=20261001090000 bundle exec rake db:migrate:up
main: == 20261001090000 AddIamRoleToAiSelfHostedModels: migrating ===================
main: -- transaction_open?(nil)
main: -> 0.0000s
main: -- add_column(:ai_self_hosted_models, :iam_role, :text, {:if_not_exists=>true})
main: -> 0.0522s
main: -- transaction_open?(nil)
main: -> 0.0000s
main: -- transaction_open?(nil)
main: -> 0.0000s
main: -- execute("ALTER TABLE ai_self_hosted_models\nADD CONSTRAINT check_cf16972fab\nCHECK ( char_length(iam_role) <= 2048 )\nNOT VALID;\n")
main: -> 0.0019s
main: -- execute("ALTER TABLE ai_self_hosted_models VALIDATE CONSTRAINT check_cf16972fab;")
main: -> 0.0020s
main: == 20261001090000 AddIamRoleToAiSelfHostedModels: migrated (0.0998s) ==========MR acceptance checklist
Evaluate this MR against the MR acceptance checklist. It helps you analyze changes to reduce risks in quality, performance, reliability, security, and maintainability.