Skip to content

Support direct Weaviate key rotation - #90

Open
bassner wants to merge 2 commits into
mainfrom
fix/pyris-weaviate-recovery
Open

Support direct Weaviate key rotation#90
bassner wants to merge 2 commits into
mainfrom
fix/pyris-weaviate-recovery

Conversation

@bassner

@bassner bassner commented Jul 29, 2026

Copy link
Copy Markdown
Member

Motivation and Context

Give the production, test, and staging Weaviate hosts independent replacement
credentials.

Related: ls1intum/artemis-ansible-collection#231

Description

  • Load the primary API key from the existing environment-specific Vault record.
  • Configure that key as the only accepted Weaviate key.
  • Add the dedicated weaviate-staging Vault mapping and use it for Artemis
    staging1/staging2.
  • Keep runtime application explicit and disabled by default.

Steps for Deployment

Weaviate prod, test, and staging are deployed. The Artemis staging1/staging2
consumer configuration remains for the Artemis owner.

@bassner
bassner requested a review from a team as a code owner July 29, 2026 11:52
@coderabbitai

coderabbitai Bot commented Jul 29, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

The Weaviate staging inventory now references the staging Vault secret and instance name. The playbook derives a primary API key, accepts only that key, and disables runtime configuration application.

Changes

Weaviate operations

Layer / File(s) Summary
Staging secret and instance alignment
group_vars/artemis_staging1.yml, group_vars/artemis_staging2.yml, hosts
Staging environments use the weaviate-staging Vault path, and the staging host uses the weaviate-staging instance name.
Key sourcing and runtime configuration
playbooks/weaviate/weaviate.yml
The playbook derives weaviate_primary_api_key from Vault, sets weaviate_accepted_api_keys to that key, and sets weaviate_apply_runtime to false.

Estimated code review effort: 2 (Simple) | ~10 minutes

Suggested reviewers: mtze, bensofficial

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title matches the main change: enabling direct Weaviate API key rotation support.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/pyris-weaviate-recovery

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@playbooks/weaviate/weaviate.yml`:
- Around line 19-30: Update the weaviate_primary_api_key resolution to use the
inline api_key only when it is defined and non-empty for var_instance_name;
otherwise fall back to the existing Vault lookup. Add validation before
rendering weaviate_accepted_api_keys to assert that the resolved primary key is
present, ensuring unresolved or empty keys fail closed.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: ae00a311-e72c-4aac-8b15-b74e767256e0

📥 Commits

Reviewing files that changed from the base of the PR and between 52d44e1 and b7d084f.

📒 Files selected for processing (2)
  • playbooks/weaviate/OWNERSHIP.md
  • playbooks/weaviate/weaviate.yml

Comment on lines +19 to +30
weaviate_primary_api_key: >-
{{
weaviate_inline_secrets[var_instance_name].api_key
if weaviate_inline_secrets is defined
else lookup(
'hashi_vault',
'kv/data/itg/services/services_ase/{0}'.format(var_instance_name)
).get('api_key')
}}
# Rotation is a direct cutover: the compromised key is never rendered.
weaviate_accepted_api_keys:
- "{{ weaviate_primary_api_key }}"

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== files =="
git ls-files | sed -n '1,200p'

echo "== target file =="
if [ -f playbooks/weaviate/weaviate.yml ]; then
  wc -l playbooks/weaviate/weaviate.yml
  cat -n playbooks/weaviate/weaviate.yml
else
  echo "missing playbooks/weaviate/weaviate.yml"
fi

echo "== search relevant symbols =="
rg -n "weaviate_inline_secrets|weaviate_primary_api_key|weaviate_accepted_api_keys|weaviate-test|var_instance_name|hashi_vault" -S .

Repository: ls1intum/artemis-ansible

Length of output: 35558


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== ownership docs =="
cat -n playbooks/weaviate/OWNERSHIP.md

echo "== group_vars weaviate files =="
for f in group_vars/artemistests_weaviate.yml group_vars/artemis_staging1.yml group_vars/artemis_staging2.yml group_vars/artemis_production.yml hosts; do
  if [ -f "$f" ]; then
    echo "--- $f ---"
    sed -n '1,180p' "$f" | cat -n
  else
    echo "missing $f"
  fi
done

echo "== ansible lookup/conditional probe =="
python3 - <<'PY'
import re
text = open("playbooks/weaviate/weaviate.yml", encoding="utf-8").read()

expr = re.search(
    r'weaviate_primary_api_key:\s*>\-?\n\s*\{\{\s*\n\s*weaviate_inline_secrets\[var_instance_name\]\.api_key\s*\n\s*if\s+weaviate_inline_secrets\s+is\s+defined',
    text,
    re.S
)
print("conditional_defined_inline_branch_present=", bool(expr))

# Model the Jinja-ish two-branch ternary semantics for key lookup, not running Ansible.
def pick(var_instance_name, secrets=None):
    if secrets is not None:
        return secrets.get(var_instance_name, {}).get("api_key")
    # fallback path would be Vault; model this as KeyError for missing Vault value.
    raise KeyError(f"kv/data/itg/services/services_ase/{var_instance_name}")

cases = {
    "defined_with_instance_key": ("weaviate-test", {"weaviate-test": {"api_key": "inline"}}),
    "defined_without_instance_key": ("weaviate-test", {"other": {"api_key": "x"}}),
    "defined_empty": ("weaviate-test", {}),
    "staging_uses_test_key": ("weaviate-test", {"weaviate-test": {"api_key": "shared"}}),
}
for name, (key, secrets) in cases.items():
    try:
        out = pick(key, secrets)
    except KeyError as e:
        print(f"{name}: fallback_path_triggered")
    else:
        print(f"{name}: inline_key_used={out!r}")
PY

echo "== role files if present =="
find . -type d -path '*weaviate*' | sed -n '1,80p'

Repository: ls1intum/artemis-ansible

Length of output: 19140


Fail closed when the inline replacement key is unavailable.

Current weaviate_staging hosts map var_instance_name to weaviate-test, so the explicit staging sharing note already covers that. The missing case is an empty/partial inline map for the selected instance: weaviate_inline_secrets is defined still selects the inline branch and renders an unresolved key instead of falling back to Vault. Only use the inline value when weaviate_inline_secrets[var_instance_name].api_key is non-empty, and assert the primary key before rendering weaviate_accepted_api_keys.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@playbooks/weaviate/weaviate.yml` around lines 19 - 30, Update the
weaviate_primary_api_key resolution to use the inline api_key only when it is
defined and non-empty for var_instance_name; otherwise fall back to the existing
Vault lookup. Add validation before rendering weaviate_accepted_api_keys to
assert that the resolved primary key is present, ensuring unresolved or empty
keys fail closed.

@bassner
bassner force-pushed the fix/pyris-weaviate-recovery branch from b7d084f to fb30ba2 Compare July 30, 2026 14:07

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

♻️ Duplicate comments (1)
playbooks/weaviate/weaviate.yml (1)

19-28: 🗄️ Data Integrity & Integration | 🟠 Major

Fail closed when the resolved key is missing or empty.

.get('api_key') can yield None or an empty string, but the value is still rendered as the sole accepted key. Add a pre-role assertion that the resolved key is a non-empty string so rotation aborts before producing an invalid authentication configuration.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@playbooks/weaviate/weaviate.yml` around lines 19 - 28, Update the pre-role
setup around weaviate_primary_api_key to assert that the resolved value is a
non-empty string before populating weaviate_accepted_api_keys. Make the
assertion fail and abort rotation when the Vault lookup returns None or an empty
value, while preserving the existing accepted-key configuration for valid keys.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@playbooks/weaviate/weaviate.yml`:
- Around line 19-25: Update the variable assignment for weaviate_primary_api_key
to explicitly select the protected offline replacement input when offline
recovery is active, otherwise retain the existing Vault lookup. Validate the
selected key before passing it to the Weaviate role, rejecting missing or empty
values while preserving the normal Vault-backed path.

---

Duplicate comments:
In `@playbooks/weaviate/weaviate.yml`:
- Around line 19-28: Update the pre-role setup around weaviate_primary_api_key
to assert that the resolved value is a non-empty string before populating
weaviate_accepted_api_keys. Make the assertion fail and abort rotation when the
Vault lookup returns None or an empty value, while preserving the existing
accepted-key configuration for valid keys.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: a0c79926-1565-490f-a5be-392e4f739410

📥 Commits

Reviewing files that changed from the base of the PR and between b7d084f and fb30ba2.

📒 Files selected for processing (1)
  • playbooks/weaviate/weaviate.yml

Comment on lines +19 to +25
weaviate_primary_api_key: >-
{{
lookup(
'hashi_vault',
'kv/data/itg/services/services_ase/{0}'.format(var_instance_name)
).get('api_key')
}}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🗄️ Data Integrity & Integration | 🟠 Major | 🏗️ Heavy lift

Honor the documented offline recovery source.

This expression always reads the key from Vault; it never consumes the protected offline replacement input described in the PR objective. During an offline recovery rotation, the playbook can therefore configure the wrong key and prevent the intended cutover. Add explicit source selection for the offline value versus Vault, then validate the selected key before passing it to the role.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@playbooks/weaviate/weaviate.yml` around lines 19 - 25, Update the variable
assignment for weaviate_primary_api_key to explicitly select the protected
offline replacement input when offline recovery is active, otherwise retain the
existing Vault lookup. Validate the selected key before passing it to the
Weaviate role, rejecting missing or empty values while preserving the normal
Vault-backed path.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant