Skip to content

feat(storage): volcengine vector db support sts token#1267

Closed
baojun-zhang wants to merge 2 commits into
volcengine:mainfrom
baojun-zhang:sts_token_suppport
Closed

feat(storage): volcengine vector db support sts token#1267
baojun-zhang wants to merge 2 commits into
volcengine:mainfrom
baojun-zhang:sts_token_suppport

Conversation

@baojun-zhang
Copy link
Copy Markdown
Collaborator

@baojun-zhang baojun-zhang commented Apr 7, 2026

Description

feat(storage): volcengine vector db support sts token

Related Issue

Type of Change

  • Bug fix (non-breaking change that fixes an issue)
  • New feature (non-breaking change that adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to not work as expected)
  • Documentation update
  • Refactoring (no functional changes)
  • Performance improvement
  • Test update

Changes Made

  • volcengine vector db support sts token

Testing

  • I have added tests that prove my fix is effective or that my feature works
  • New and existing unit tests pass locally with my changes
  • I have tested this on the following platforms:
    • Linux
    • macOS
    • Windows

Checklist

  • My code follows the project's coding style
  • I have performed a self-review of my code
  • I have commented my code, particularly in hard-to-understand areas
  • I have made corresponding changes to the documentation
  • My changes generate no new warnings
  • Any dependent changes have been merged and published

Screenshots (if applicable)

Additional Notes

@github-actions
Copy link
Copy Markdown

github-actions Bot commented Apr 7, 2026

PR Reviewer Guide 🔍

Here are some key observations to aid the review process:

⏱️ Estimated effort to review: 3 🔵🔵🔵⚪⚪
🏅 Score: 85
🧪 PR contains tests
🔒 No security concerns identified
✅ No TODO sections
🔀 No multiple PR themes
⚡ Recommended focus areas for review

Unrelated Change

This file modifies Vault provider test fixtures which are unrelated to the Volcengine STS token feature, increasing PR scope and review complexity.

class TestVaultProviderIntegration:
    """Integration tests for VaultProvider."""

    @pytest_asyncio.fixture(scope="function")
    async def vault_provider(self):
        """Fixture that provides a VaultProvider instance."""
        provider = VaultProvider(
            addr=VAULT_ADDR, token=VAULT_TOKEN, mount_path=VAULT_MOUNT_PATH, kv_version=2
        )
        yield provider

    @pytest.fixture(scope="function")
    def vault_config(self):
        """Fixture that provides Vault configuration."""
        return {
            "vault": {
                "address": VAULT_ADDR,
                "token": VAULT_TOKEN,
                "mount_point": VAULT_MOUNT_PATH,
                "kv_version": 2,
            }
        }

    async def test_vault_provider_initialization(self, vault_provider):
        """Test VaultProvider initialization and Vault connection."""
        client = await vault_provider._get_client()
        assert client is not None
        assert client.is_authenticated()

    async def test_derive_account_key(self, vault_provider):
        """Test deriving account keys."""
        account_id = "test-account-vault"
        account_key = await vault_provider.derive_account_key(account_id)

        assert account_key is not None
        assert isinstance(account_key, bytes)
        assert len(account_key) == 32

    async def test_derive_different_account_keys(self, vault_provider):
        """Test that different accounts get different keys."""
        account1_key = await vault_provider.derive_account_key("account-1")
        account2_key = await vault_provider.derive_account_key("account-2")

        assert account1_key != account2_key

    async def test_derive_same_account_key_consistent(self, vault_provider):
        """Test that same account gets consistent key."""
        key1 = await vault_provider.derive_account_key("test-account")
        key2 = await vault_provider.derive_account_key("test-account")

        assert key1 == key2

    async def test_encrypt_decrypt_file_key(self, vault_provider):
        """Test encrypting and decrypting file keys."""
        plaintext_key = secrets.token_bytes(32)
        account_id = "test-account-encrypt"

        encrypted_key, iv = await vault_provider.encrypt_file_key(plaintext_key, account_id)

        assert encrypted_key is not None
        assert isinstance(encrypted_key, bytes)
        assert encrypted_key != plaintext_key
        assert iv is not None
        assert isinstance(iv, bytes)

        decrypted = await vault_provider.decrypt_file_key(encrypted_key, iv, account_id)

        assert decrypted == plaintext_key

    async def test_encrypt_decrypt_multiple_keys(self, vault_provider):
        """Test encrypting and decrypting multiple different keys."""
        key1 = secrets.token_bytes(32)
        key2 = secrets.token_bytes(32)
        account_id = "test-account-multiple"

        encrypted1, iv1 = await vault_provider.encrypt_file_key(key1, account_id)
        encrypted2, iv2 = await vault_provider.encrypt_file_key(key2, account_id)

        assert encrypted1 != encrypted2

        decrypted1 = await vault_provider.decrypt_file_key(encrypted1, iv1, account_id)
        decrypted2 = await vault_provider.decrypt_file_key(encrypted2, iv2, account_id)

        assert decrypted1 == key1
        assert decrypted2 == key2

    async def test_create_root_key_provider_vault(self, vault_config):
        """Test creating VaultProvider via create_root_key_provider."""
        provider = create_root_key_provider("vault", vault_config)

        assert provider is not None
        assert isinstance(provider, VaultProvider)

    async def test_get_root_key(self, vault_provider):
        """Test getting root key."""
        root_key = await vault_provider.get_root_key()

        assert root_key is not None
        assert isinstance(root_key, bytes)
        assert len(root_key) > 0

    async def test_full_roundtrip(self, vault_provider):
        """Test full encryption/decryption roundtrip."""
        # Derive account key
        account_id = "test-account-roundtrip"
        account_key = await vault_provider.derive_account_key(account_id)

        assert account_key is not None
        assert len(account_key) == 32

        # Generate and encrypt file key
        file_key = secrets.token_bytes(32)
        encrypted_key, iv = await vault_provider.encrypt_file_key(file_key, account_id)

        assert encrypted_key is not None
        assert isinstance(encrypted_key, bytes)
        assert iv is not None
        assert isinstance(iv, bytes)

        # Decrypt and verify
        decrypted_key = await vault_provider.decrypt_file_key(encrypted_key, iv, account_id)

        assert decrypted_key == file_key


class TestVaultProviderErrors:
    """Test error handling for VaultProvider."""

    async def test_invalid_token(self):
        """Test with invalid token."""
        provider = VaultProvider(
            addr="http://127.0.0.1:8200", token="invalid-token", mount_path="transit"
        )

        with pytest.raises(AuthenticationFailedError):
            await provider._get_client()

    async def test_invalid_address(self):
        """Test with invalid address."""
        provider = VaultProvider(
            addr="http://invalid-address-that-does-not-exist:8200",
            token="test-token",
            mount_path="transit",
        )

        with pytest.raises(Exception):  # noqa: B017
            await provider._get_client()

    def test_create_provider_missing_config(self):
        """Test creating provider with missing config."""
        with pytest.raises(ConfigError):
            create_root_key_provider("vault", {})

    def test_create_provider_missing_token(self):
        """Test creating provider with missing token."""
        with pytest.raises(ConfigError):
            create_root_key_provider("vault", {"vault": {"address": "http://127.0.0.1:8200"}})

    def test_create_provider_missing_address(self):
        """Test creating provider with missing address."""
        with pytest.raises(ConfigError):
            create_root_key_provider("vault", {"vault": {"token": "test-token"}})


@pytest_asyncio.fixture(scope="function")
async def vault_encryption_config():
    """Fixture that provides encryption configuration with Vault provider"""
    return {
        "encryption": {
            "enabled": True,
            "provider": "vault",
            "vault": {
                "address": VAULT_ADDR,
                "token": VAULT_TOKEN,
                "mount_point": VAULT_MOUNT_PATH,
                "kv_version": 2,
            },
        }
    }


@pytest_asyncio.fixture(scope="function")
async def vault_file_encryptor():
    """Fixture that provides a FileEncryptor instance with Vault provider for testing"""
    provider = VaultProvider(
        addr=VAULT_ADDR, token=VAULT_TOKEN, mount_path=VAULT_MOUNT_PATH, kv_version=2
    )
    return FileEncryptor(provider)


@pytest_asyncio.fixture(scope="function")
async def openviking_client_with_vault_encryption(test_data_dir: Path, vault_encryption_config):
    """Fixture that provides an OpenViking client with Vault encryption enabled"""

@github-actions
Copy link
Copy Markdown

github-actions Bot commented Apr 7, 2026

PR Code Suggestions ✨

No code suggestions found for the PR.

@github-project-automation github-project-automation Bot moved this from Backlog to Done in OpenViking project Apr 7, 2026
@baojun-zhang baojun-zhang deleted the sts_token_suppport branch April 7, 2026 05:00
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

1 participant