Skip to content

Installation Validation: Teams Access#

System Criticality: Business-Critical Validation Approach: Risk-based Related Design: DESIGN:TeamsAccess Related URS: @URS:TeamsAccess Related Risks: RISK:TeamsAccess


Test Strategy#

Level Purpose Owner When
Unit Individual Graph API client methods Developers During development (pytest)
Integration MCP tool → Graph client → Microsoft Graph API QA After code freeze
System End-to-end MCP protocol flows QA Before deployment to production
Security OAuth2 enforcement, access control, data protection Security Team Before production release
Performance Throttling handling, response times QA Before production release

Validation Focus: Security and privacy controls take precedence over functional testing due to the sensitive nature of Teams message data (confidential business communications, HR discussions, meeting notes, personal chat content).

Test Execution: Integration and system tests require two Azure AD test users with distinct Teams memberships to validate user-scoped access boundaries.


Traceability Matrix#

Requirement Summary Risk Test Case Type Status
URS:TeamsAccess - ListTeams User can list joined teams RISK:TeamsAccess-R3 TEST-001 Integration Not Started
URS:TeamsAccess - ListChannels User can list team channels RISK:TeamsAccess-R7 TEST-002 Integration Not Started
URS:TeamsAccess - ListChannelMessages User can list channel messages RISK:TeamsAccess-R1 TEST-003 Integration Not Started
URS:TeamsAccess - GetReplies User can fetch message replies RISK:TeamsAccess-R1 TEST-004 Integration Not Started
URS:TeamsAccess - ListChats User can list chats RISK:TeamsAccess-R4 TEST-005 Integration Not Started
URS:TeamsAccess - ListChatMessages User can list chat messages RISK:TeamsAccess-R3 TEST-006 Integration Not Started
URS:TeamsAccess - ListChatMembers User can list chat members RISK:TeamsAccess-R4 TEST-007 Integration Not Started
URS:TeamsAccess - SearchMessages User can search across channels/chats RISK:TeamsAccess-R5 TEST-008 Integration Not Started
URS:TeamsAccess - UserScoped Only user's teams/chats accessible RISK:TeamsAccess-R3 TEST-SEC-001 Security Not Started
URS:TeamsAccess - ReadOnly No write operations possible RISK:TeamsAccess-R1 TEST-SEC-002 Security Not Started
URS:TeamsAccess - PrivacyPreservation Message content not persisted/logged RISK:TeamsAccess-R2 TEST-SEC-003 Security Not Started
URS:TeamsAccess - PrivacyPreservation Chat confidentiality maintained RISK:TeamsAccess-R4 TEST-SEC-004 Security Not Started
URS:TeamsAccess - UserScoped Unauthenticated requests rejected RISK:TeamsAccess-R1 TEST-SEC-005 Security Not Started
URS:TeamsAccess - UserScoped Private channel access restricted RISK:TeamsAccess-R7 TEST-SEC-006 Security Not Started

Coverage: 15/15 security and functional requirements = 100%


Test Cases#

TEST-001: List Teams User Is Member Of#

Related: URS:TeamsAccess - ListTeams | RISK:TeamsAccess-R3 Risk Level: Medium

Purpose: Verify that list_teams returns only teams the authenticated user is a member of, enforcing user-scoped access.

Preconditions: - Teams MCP server deployed and available - Test user authenticated with valid OAuth2 token (Azure AD OBO flow completed) - Test user is a member of at least 2 teams

Steps: 1. Invoke list_teams MCP tool via authenticated session 2. Verify Microsoft Graph API call: GET https://graph.microsoft.com/v1.0/me/joinedTeams 3. Inspect response payload

Expected Results: - HTTP 200 response from Microsoft Graph API - Response contains array of team objects - Each team includes: id, displayName, description - Only teams where user is a member are returned - No teams from other users are visible

Pass Criteria: - All expected fields present in response - Team count matches user's actual membership (verify via Teams UI) - Response completes within 2 seconds (p95)


TEST-002: List Channels Including Private Channels#

Related: URS:TeamsAccess - ListChannels | RISK:TeamsAccess-R7 Risk Level: Medium

Purpose: Verify that list_channels returns channels (standard, private, shared) for a specific team, respecting user membership.

Preconditions: - Test user authenticated - Test user is member of a team containing at least one private channel - Test user is member of that private channel

Steps: 1. Invoke list_teams to get a valid team_id 2. Invoke list_channels with team_id parameter 3. Verify Microsoft Graph API call: GET https://graph.microsoft.com/v1.0/teams/{team_id}/channels 4. Inspect response payload

Expected Results: - HTTP 200 response from Microsoft Graph API - Response contains array of channel objects - Each channel includes: id, displayName, description, membershipType, webUrl - Private channels where user is a member are included - Standard channels are included - membershipType field correctly indicates "private", "shared", or "standard"

Pass Criteria: - All expected fields present - Private channel access respects user membership (confirmed via Teams UI) - Response completes within 2 seconds (p95)


TEST-003: List Messages in Public Channel#

Related: URS:TeamsAccess - ListChannelMessages | RISK:TeamsAccess-R1 Risk Level: High

Purpose: Verify that list_channel_messages returns message content from a public team channel.

Preconditions: - Test user authenticated - Test user is member of a team with a public channel containing at least 5 messages

Steps: 1. Invoke list_teams and list_channels to get valid team_id and channel_id (standard membership type) 2. Invoke list_channel_messages with team_id, channel_id, count=25 3. Verify Microsoft Graph API call: GET https://graph.microsoft.com/v1.0/teams/{team_id}/channels/{channel_id}/messages?$top=25 4. Inspect response payload

Expected Results: - HTTP 200 response from Microsoft Graph API - Response contains array of message objects (up to 25) - Each message includes: id, subject, body, attachments, from, createdDateTime, webUrl - Message body contains actual text content - Sender information (from field) includes display name and email

Pass Criteria: - All expected fields present - Message content matches what is visible in Teams UI - Response completes within 3 seconds (p95)


TEST-004: Get Replies to Channel Message#

Related: URS:TeamsAccess - GetReplies | RISK:TeamsAccess-R1 Risk Level: Medium

Purpose: Verify that get_channel_message_replies returns reply thread for a specific message.

Preconditions: - Test user authenticated - Test user has access to a channel message with at least 2 replies

Steps: 1. Invoke list_channel_messages to get a valid message_id from a message with replies 2. Invoke get_channel_message_replies with team_id, channel_id, message_id, count=25 3. Verify Microsoft Graph API call: GET https://graph.microsoft.com/v1.0/teams/{team_id}/channels/{channel_id}/messages/{message_id}/replies?$top=25 4. Inspect response payload

Expected Results: - HTTP 200 response from Microsoft Graph API - Response contains array of reply message objects (up to 25) - Each reply includes: id, subject, body, attachments, from, createdDateTime, webUrl - Reply content matches Teams UI

Pass Criteria: - All expected fields present - Reply count matches actual thread in Teams UI - Response completes within 2 seconds (p95)


TEST-005: List Chats Including Meeting Chats#

Related: URS:TeamsAccess - ListChats | RISK:TeamsAccess-R4 Risk Level: Medium

Purpose: Verify that list_chats returns all chat types (oneOnOne, group, meeting) user participates in, including meeting chats that may contain sensitive meeting notes.

Preconditions: - Test user authenticated - Test user participates in at least one 1:1 chat, one group chat, and one meeting chat

Steps: 1. Invoke list_chats with count=50, no filters 2. Verify Microsoft Graph API call: GET https://graph.microsoft.com/v1.0/me/chats?$top=50 3. Inspect response payload for presence of all chat types

Expected Results: - HTTP 200 response from Microsoft Graph API - Response contains array of chat objects (up to 50) - Each chat includes: id, topic, chatType, createdDateTime, viewpoint, webUrl - Meeting chats (chatType=meeting) are included in results - Group chats (chatType=group) are included - 1:1 chats (chatType=oneOnOne) are included

Pass Criteria: - All expected chat types present in response - Meeting chats are not excluded by default (validating RISK:TeamsAccess-R4 concern) - Chat count matches user's actual chats (verify via Teams UI) - Response completes within 2 seconds (p95)


TEST-006: List Messages in Private Chat#

Related: URS:TeamsAccess - ListChatMessages | RISK:TeamsAccess-R3 Risk Level: High

Purpose: Verify that list_chat_messages returns messages from a private chat, respecting user membership.

Preconditions: - Test user authenticated - Test user participates in a 1:1 chat with at least 5 messages

Steps: 1. Invoke list_chats to get a valid chat_id (chatType=oneOnOne) 2. Invoke list_chat_messages with chat_id, count=25 3. Verify Microsoft Graph API call: GET https://graph.microsoft.com/v1.0/me/chats/{chat_id}/messages?$top=25 4. Inspect response payload

Expected Results: - HTTP 200 response from Microsoft Graph API - Response contains array of message objects (up to 25) - Each message includes: id, subject, body, attachments, from, createdDateTime, webUrl - Message content matches Teams UI - Only messages from specified chat are returned

Pass Criteria: - All expected fields present - Chat message content accessible to user (user is chat participant) - Response completes within 2 seconds (p95)


TEST-007: List Members in Group Chat#

Related: URS:TeamsAccess - ListChatMembers | RISK:TeamsAccess-R4 Risk Level: Medium

Purpose: Verify that list_chat_members returns all participants in a chat.

Preconditions: - Test user authenticated - Test user participates in a group chat with at least 3 members

Steps: 1. Invoke list_chats to get a valid chat_id (chatType=group) 2. Invoke list_chat_members with chat_id 3. Verify Microsoft Graph API call: GET https://graph.microsoft.com/v1.0/me/chats/{chat_id}/members 4. Inspect response payload

Expected Results: - HTTP 200 response from Microsoft Graph API - Response contains array of member objects - Each member includes: id, displayName, email - Member list matches actual chat participants (verify via Teams UI)

Pass Criteria: - All expected fields present - Member count accurate - Response completes within 2 seconds (p95)


TEST-008: Search Messages Across Teams and Chats#

Related: URS:TeamsAccess - SearchMessages | RISK:TeamsAccess-R5 Risk Level: Medium

Purpose: Verify that search_messages searches across all accessible channels and chats, returning summary snippets.

Preconditions: - Test user authenticated - Test user has access to multiple teams/channels/chats containing the search term "project update"

Steps: 1. Invoke search_messages with query_text="project update", size=25 2. Verify Microsoft Graph API call: POST https://graph.microsoft.com/v1.0/search/query with entity type chatMessage 3. Inspect response payload

Expected Results: - HTTP 200 response from Microsoft Graph API - Response contains array of message objects (up to 25) - Each result includes: id, createdDateTime, subject, from, channelIdentity, chatId, webLink, summary - summary field contains message content snippet with search term context - Results only include messages from teams/channels/chats user has access to

Pass Criteria: - All expected fields present - Search respects user-scoped access (no results from inaccessible teams) - Search term appears in summary field - Response completes within 2 seconds (p95)


Security Tests#

TEST-SEC-001: User-Scoped Teams Access Enforcement#

Related: URS:TeamsAccess - UserScoped | RISK:TeamsAccess-R3 Risk Level: Critical

Purpose: Verify that User A cannot access User B's private chats or teams by manipulating IDs or tokens.

Preconditions: - Two test users authenticated: User A and User B - User A is member of Team Alpha (User B is not) - User B is member of Team Beta (User A is not) - User A has a private chat with User C (User B is not participant)

Test Cases:

TEST-SEC-001a: Cross-User Team Access Prevention#

Steps: 1. User A authenticates and retrieves list_teams 2. User A notes Team Alpha ID 3. User B authenticates and attempts to access Team Alpha via list_channels(team_id=<Team Alpha ID>)

Expected: - Microsoft Graph API returns HTTP 403 Forbidden or empty channel list - No Team Alpha channels visible to User B - CloudWatch logs show access attempt with User B's identity (no User A data leaked)


TEST-SEC-001b: Cross-User Chat Access Prevention#

Steps: 1. User A authenticates and retrieves list_chats 2. User A notes private chat ID with User C 3. User B authenticates and attempts to access this chat via list_chat_messages(chat_id=<User A's chat ID>)

Expected: - Microsoft Graph API returns HTTP 403 Forbidden - No message content from User A's chat visible to User B - Error message does not reveal User A's chat details


TEST-SEC-001c: Private Channel Access Restriction#

Steps: 1. User A is member of private channel "HR Confidential" in Team Alpha 2. User B is member of Team Alpha but NOT member of "HR Confidential" 3. User B authenticates and lists channels for Team Alpha 4. User B attempts to access "HR Confidential" channel messages via list_channel_messages(channel_id=<HR Confidential ID>)

Expected: - Private channel "HR Confidential" does not appear in User B's list_channels response, OR - Microsoft Graph API returns HTTP 403 Forbidden when User B attempts to list messages - No message content from private channel visible to non-member

Pass Criteria: - All cross-user access attempts denied - No data leakage in error messages - Access denials logged correctly with requesting user identity


TEST-SEC-002: Read-Only Operations Enforcement#

Related: URS:TeamsAccess - ReadOnly | RISK:TeamsAccess-R1 Risk Level: High

Purpose: Verify that the Teams MCP server cannot be used to send, modify, or delete Teams messages.

Preconditions: - Test user authenticated with token containing read-only scopes: Team.ReadBasic.All, Channel.ReadBasic.All, ChannelMessage.Read.All, Chat.Read, ChatMessage.Read

Test Cases:

TEST-SEC-002a: Message Sending Attempt via Graph API#

Steps: 1. Manually craft a POST request to https://graph.microsoft.com/v1.0/teams/{team_id}/channels/{channel_id}/messages using the OBO-exchanged token 2. Attempt to send a new message

Expected: - Microsoft Graph API returns HTTP 403 Forbidden (insufficient scopes) - Error message indicates missing ChannelMessage.Send scope - No message posted to Teams channel


TEST-SEC-002b: Message Deletion Attempt#

Steps: 1. Attempt to DELETE a message via https://graph.microsoft.com/v1.0/teams/{team_id}/channels/{channel_id}/messages/{message_id} using the token 2. Verify response

Expected: - Microsoft Graph API returns HTTP 403 Forbidden - Message not deleted (verify in Teams UI)


TEST-SEC-002c: Tool Inventory Review#

Steps: 1. Review MCP tool definitions in connectors/mcps/teams/src/teams_mcp/server.py 2. Verify no tools implement write operations (send, modify, delete, create channels)

Expected: - Only read operations exposed as MCP tools: list_teams, list_channels, list_channel_messages, get_channel_message_replies, list_chats, list_chat_messages, list_chat_members, search_messages - No write-capable tools present

Pass Criteria: - All write attempts rejected by Microsoft Graph API due to scope restrictions - No write operation tools exist in MCP server


TEST-SEC-003: Message Content Not Persisted to DynamoDB#

Related: URS:TeamsAccess - PrivacyPreservation | RISK:TeamsAccess-R2 Risk Level: High

Purpose: Verify that Teams message body, subject, sender, and participant data are not written to DynamoDB token storage.

Preconditions: - Test user authenticated - Test user retrieves channel messages and chat messages containing known test content

Steps: 1. Invoke list_channel_messages to retrieve messages containing test string "CONFIDENTIAL_TEST_CONTENT_12345" 2. Invoke list_chat_messages to retrieve chat messages 3. Query DynamoDB table mcp-oauth-storage-teams-mcp-{env} for all items with partition key = test user's oid claim 4. Inspect DynamoDB item attributes

Expected Results: - DynamoDB items contain ONLY: user_id, session_id, access_token, refresh_token, expires_at - No attributes named: body, content, message, subject, from, sender, participant, displayName - Test string "CONFIDENTIAL_TEST_CONTENT_12345" not found anywhere in DynamoDB table

Pass Criteria: - Zero message content persisted to DynamoDB - Only OAuth token data stored - No PII or message metadata stored


TEST-SEC-004: Chat Confidentiality — No Logging of Message Content#

Related: URS:TeamsAccess - PrivacyPreservation | RISK:TeamsAccess-R4 Risk Level: Critical

Purpose: Verify that private/1:1 chat message content is not written to CloudWatch logs or any persistent storage.

Preconditions: - Test user authenticated - Test user has a 1:1 chat containing message with test string "HR_SENSITIVE_PERFORMANCE_REVIEW_67890"

Steps: 1. Invoke list_chats and list_chat_messages to retrieve the test message 2. Query CloudWatch Logs Insights for log group /ecs/teams-mcp-{env} with filter: HR_SENSITIVE_PERFORMANCE_REVIEW_67890 3. Query CloudWatch Logs Insights for log group with filter: displayName or body.content 4. Inspect Python application code in connectors/mcps/teams/src/teams_mcp/tools/ for logging calls

Expected Results: - CloudWatch query for test string returns ZERO results - CloudWatch query for displayName, body.content, subject returns ZERO results (except structured log field names without values) - Application code uses structured logging with field exclusion: - Logs: message_count, chat_id, channel_id, team_id, date_range, filters - Does NOT log: body, content, subject, from.user.displayName, summary - Log level set to INFO or higher (no DEBUG logging in production)

Pass Criteria: - Zero chat message content in CloudWatch logs - Zero sender/participant names in logs - Only metadata (IDs, counts, timestamps) logged


TEST-SEC-005: Unauthenticated Request Rejection#

Related: URS:TeamsAccess - UserScoped | RISK:TeamsAccess-R1 Risk Level: Critical

Purpose: Verify that requests without a valid OAuth2 Bearer token are rejected before any Teams data is accessed.

Preconditions: - Teams MCP server deployed

Test Cases:

TEST-SEC-005a: Missing Authorization Header#

Steps: 1. Send HTTP POST request to MCP server /mcp endpoint with list_teams tool invocation 2. Omit Authorization header

Expected: - HTTP 401 Unauthorized response - Error message: "Missing or invalid authentication" - No Microsoft Graph API call made (verify in CloudWatch logs)


TEST-SEC-005b: Invalid Bearer Token#

Steps: 1. Send HTTP POST request with Authorization: Bearer invalid_token_12345 2. Attempt to invoke list_teams

Expected: - HTTP 401 Unauthorized response (from OBO exchange failure) - Error message indicates token validation failure - No Teams data returned


TEST-SEC-005c: Expired OAuth Token#

Steps: 1. Obtain a valid OAuth2 token 2. Wait for token expiration (61 minutes after issuance, or modify expires_at in test to simulate expiration) 3. Attempt to invoke list_teams with expired token

Expected: - HTTP 401 Unauthorized response - Microsoft Graph API rejects token with "Access token has expired" error - User prompted to re-authenticate

Pass Criteria: - All unauthenticated requests rejected at authentication layer - No Teams data accessible without valid token - Error messages do not leak sensitive information


TEST-SEC-006: Private Channel Access Boundary Validation#

Related: URS:TeamsAccess - UserScoped | RISK:TeamsAccess-R7 Risk Level: High

Purpose: Verify that a user cannot read messages from a Teams private channel they are not a member of, even if they are a member of the parent team.

Preconditions: - Team "Product Engineering" exists - Private channel "Salary Review" exists in "Product Engineering" team - User A is member of "Product Engineering" team but NOT member of "Salary Review" channel - User B is member of "Salary Review" channel - "Salary Review" channel contains messages with test string "SALARY_ADJUSTMENT_2026"

Steps: 1. User A authenticates and invokes list_teams 2. User A identifies "Product Engineering" team ID 3. User A invokes list_channels(team_id=<Product Engineering ID>) 4. Verify whether "Salary Review" channel appears in response 5. If channel appears: User A attempts to invoke list_channel_messages(team_id=..., channel_id=<Salary Review ID>) 6. If channel does not appear: User A manually crafts channel ID (if known via other means) and attempts access

Expected Results: - Option 1 (Microsoft Graph API filtering): "Salary Review" private channel does NOT appear in User A's list_channels response - Option 2 (Access control at message level): Channel appears in list, but list_channel_messages returns HTTP 403 Forbidden for User A - Test string "SALARY_ADJUSTMENT_2026" NOT visible to User A under any circumstances - User B (member) successfully accesses "Salary Review" channel and sees messages

Pass Criteria: - Private channel messages inaccessible to non-members - Access denial occurs at Microsoft Graph API layer (not MCP server) - CloudWatch logs record access attempt with User A's identity (no message content logged)


Performance Tests#

TEST-PERF-001: Microsoft Graph API Throttling Response#

Related: RISK:TeamsAccess-R6 Risk Level: Medium

Purpose: Verify that the MCP server correctly handles Microsoft Graph API 429 rate limit responses, respecting Retry-After header and propagating error to client.

Preconditions: - Test user authenticated - Test environment configured to trigger rate limiting (simulate by repeatedly calling list_channel_messages on same channel in rapid succession)

Steps: 1. Invoke list_channel_messages for the same channel 10 times within 3 seconds (Teams APIs throttle at ~3 req/s per channel) 2. Monitor Microsoft Graph API responses for HTTP 429 3. Verify MCP server response to client 4. Inspect CloudWatch logs for retry behavior

Expected Results: - Microsoft Graph API returns HTTP 429 Too Many Requests after ~3 requests/second - Response includes Retry-After header (e.g., Retry-After: 5) - MCP server propagates 429 error to client with Retry-After value - MCP server does NOT automatically retry (caller must back off) - CloudWatch logs record throttling event: graph_api_throttled with retry_after value

Pass Criteria: - Throttling errors handled gracefully - Retry-After header respected and communicated to client - No infinite retry loops


TEST-PERF-002: Response Time Validation#

Related: DESIGN:TeamsAccess - Performance Risk Level: Low

Purpose: Verify that MCP tool response times meet design targets under normal load.

Preconditions: - Test user authenticated - Microsoft Graph API operating normally (no throttling)

Target Response Times (p95): - list_teams: < 2s - list_channels: < 2s - list_chats: < 2s - list_channel_messages (no expand): < 2s - list_channel_messages (expand="replies"): < 3s - search_messages: < 2s

Steps: 1. Execute each MCP tool 20 times 2. Measure end-to-end latency (client request → MCP response) 3. Calculate p95 latency for each tool

Expected Results: - 95% of requests complete within target response time - No timeouts or errors

Pass Criteria: - All tools meet p95 latency targets


Quality Gates#

Before production deployment: - [ ] All security tests passed (TEST-SEC-001 through TEST-SEC-006) - [ ] All integration tests passed (TEST-001 through TEST-008) - [ ] Zero critical defects - [ ] Zero high-severity defects related to data protection or access control - [ ] CloudWatch log inspection confirms no message content or PII logged - [ ] DynamoDB inspection confirms no message data persisted (only OAuth tokens) - [ ] Performance tests passed (throttling handling, response time targets met) - [ ] Azure AD app registration permissions verified: read-only scopes only - [ ] Code review completed: no write operations implemented - [ ] Security team sign-off obtained

Blocking Issues: - Any failure of TEST-SEC-001 (cross-user access), TEST-SEC-003 (data persistence), TEST-SEC-004 (log content), or TEST-SEC-005 (auth bypass) BLOCKS production deployment


Test Environment#

Environments: - Dev: https://teams.dev.connectors.novo-genai.com - Prod: https://teams.connectors.novo-genai.com (post-validation only)

Test Data: - Two Azure AD test users with distinct Teams memberships: - testuser-teams-a@novonordisk.com (Team Alpha, private channel "HR Confidential") - testuser-teams-b@novonordisk.com (Team Beta, no private channel access) - Test team: "Product Engineering" with public channel "General" and private channel "Salary Review" - Test chat: 1:1 chat between test users containing known test strings - Test meeting chat: Meeting chat from test calendar event

Azure AD Test App Registration: - Dev Client ID: 7e0b850a-21c6-4393-ab47-bfdd5ac59f6b - Scopes: Team.ReadBasic.All, Channel.ReadBasic.All, ChannelMessage.Read.All, Chat.Read, ChatMessage.Read, offline_access

CloudWatch Logs: - Log group: /ecs/teams-mcp-dev - Retention: 90 days - Encryption: Enabled (AWS KMS)

DynamoDB: - Table: mcp-oauth-storage-teams-mcp-dev - Partition key: user_id - Sort key: session_id


Test Execution Notes#

Multi-User Test Setup#

Security tests require coordinated execution: 1. Provision two test users in Azure AD with different Teams memberships 2. Create a shared team with both users as members, containing a private channel accessible to only one user 3. Establish 1:1 chat between test users for chat access testing 4. Document team IDs, channel IDs, and chat IDs for test case execution

Log Inspection Procedure#

For TEST-SEC-004 (log content inspection):

# CloudWatch Logs Insights query
fields @timestamp, @message
| filter @message like /body|content|displayName|subject|from/
| filter @logStream like /teams-mcp-dev/
| sort @timestamp desc
| limit 1000
Expected result: Zero matches (only field names in structured log schema, no values)

DynamoDB Inspection Procedure#

For TEST-SEC-003 (DynamoDB persistence check):

aws dynamodb scan \
  --table-name mcp-oauth-storage-teams-mcp-dev \
  --filter-expression "contains(attribute_not_exists(#msg), :test_string)" \
  --expression-attribute-names '{"#msg":"message"}' \
  --expression-attribute-values '{":test_string":{"S":"CONFIDENTIAL"}}'
Expected result: No items with message content attributes


Test Results Summary#

(To be completed during validation execution)

Test Case Executed By Date Result Notes
TEST-001
TEST-002
TEST-003
TEST-004
TEST-005
TEST-006
TEST-007
TEST-008
TEST-SEC-001a
TEST-SEC-001b
TEST-SEC-001c
TEST-SEC-002a
TEST-SEC-002b
TEST-SEC-002c
TEST-SEC-003
TEST-SEC-004
TEST-SEC-005a
TEST-SEC-005b
TEST-SEC-005c
TEST-SEC-006
TEST-PERF-001
TEST-PERF-002

Version: 1.0 Date: 2026-04-22 Prepared by: QA Team Approved by: (Pending execution and review)