Skip to content

Add Agentic Knowledge Discovery sample - #111

Draft
razkenari wants to merge 1 commit into
aws-samples:mainfrom
razkenari:add-agentic-knowledge-discovery
Draft

Add Agentic Knowledge Discovery sample#111
razkenari wants to merge 1 commit into
aws-samples:mainfrom
razkenari:add-agentic-knowledge-discovery

Conversation

@razkenari

Copy link
Copy Markdown
Collaborator

Summary

Adds a new sample, Agentic Knowledge Discovery, to samples/agentic-knowledge-discovery/. The sample demonstrates an agent that combines unstructured document search (Amazon Bedrock Knowledge Bases, OpenSearch Serverless, Nova multimodal embeddings) with structured metadata search (Aurora PostgreSQL) to plan retrieval across both, then answers with page-level citations. It ships two agent implementations (Strands and LangGraph) behind an AG-UI frontend, following the same construct-based CDK pattern as core FAST.

Built on FAST v0.4.2.

Key differences from FAST

  • Two AgentCore Gateway retrieval tools: doc_search (Bedrock Knowledge Base) and structured_search (read-only SQL over Aurora), sharing a doc_id and metadata keys so the agent can filter by attribute then search content.
  • Bedrock Knowledge Base construct: OpenSearch Serverless, Amazon Nova multimodal embeddings, hierarchical chunking, Bedrock Data Automation parsing.
  • Minimal NAT-free VPC for the data plane (Aurora + in-VPC tool Lambdas only); the runtime and doc_search stay outside the VPC.
  • Page-level citations and follow-up question suggestions.
  • Frontend: session sidebar (list/resume/delete), grouped tool-call display.

A FAST-based agent that answers questions over a mix of unstructured documents
(Bedrock Knowledge Base) and structured metadata (Aurora PostgreSQL), with
metadata-filtered retrieval, page-level citations, follow-up suggestions, and
both Strands and LangGraph patterns.
@github-actions

Copy link
Copy Markdown

Latest scan for commit: 2211dc2 | Updated: 2026-07-19 01:19:44 UTC

Security Scan Results

Scan Metadata

  • Project: ASH
  • Scan executed: 2026-07-19T01:19:31+00:00
  • ASH version: 3.2.2

Summary

Scanner Results

The table below shows findings by scanner, with status based on severity thresholds and dependencies:

Column Explanations:

Severity Levels (S/C/H/M/L/I):

  • Suppressed (S): Security findings that have been explicitly suppressed/ignored and don't affect the scanner's pass/fail status
  • Critical (C): The most severe security vulnerabilities requiring immediate remediation (e.g., SQL injection, remote code execution)
  • High (H): Serious security vulnerabilities that should be addressed promptly (e.g., authentication bypasses, privilege escalation)
  • Medium (M): Moderate security risks that should be addressed in normal development cycles (e.g., weak encryption, input validation issues)
  • Low (L): Minor security concerns with limited impact (e.g., information disclosure, weak recommendations)
  • Info (I): Informational findings for awareness with minimal security risk (e.g., code quality suggestions, best practice recommendations)

Other Columns:

  • Time: Duration taken by each scanner to complete its analysis
  • Action: Total number of actionable findings at or above the configured severity threshold that require attention

Scanner Results:

  • PASSED: Scanner found no security issues at or above the configured severity threshold - code is clean for this scanner
  • FAILED: Scanner found security vulnerabilities at or above the threshold that require attention and remediation
  • MISSING: Scanner could not run because required dependencies/tools are not installed or available
  • SKIPPED: Scanner was intentionally disabled or excluded from this scan
  • ERROR: Scanner encountered an execution error and could not complete successfully

Severity Thresholds (Thresh Column):

  • CRITICAL: Only Critical severity findings cause scanner to fail
  • HIGH: High and Critical severity findings cause scanner to fail
  • MEDIUM (MED): Medium, High, and Critical severity findings cause scanner to fail
  • LOW: Low, Medium, High, and Critical severity findings cause scanner to fail
  • ALL: Any finding of any severity level causes scanner to fail

Threshold Source: Values in parentheses indicate where the threshold is configured:

  • (g) = global: Set in the global_settings section of ASH configuration
  • (c) = config: Set in the individual scanner configuration section
  • (s) = scanner: Default threshold built into the scanner itself

Statistics calculation:

  • All statistics are calculated from the final aggregated SARIF report
  • Suppressed findings are counted separately and do not contribute to actionable findings
  • Scanner status is determined by comparing actionable findings to the threshold
Scanner S C H M L I Time Action Result Thresh
bandit 0 0 0 0 0 0 678ms 0 PASSED MED (g)
cdk-nag 0 0 0 0 0 0 14.2s 0 PASSED MED (g)
cfn-nag 0 0 0 0 0 0 2.8s 0 PASSED MED (g)
checkov 0 4 0 0 0 0 8.7s 4 FAILED MED (g)
detect-secrets 0 0 0 0 0 0 2.0s 0 PASSED MED (g)
grype 0 0 0 0 0 0 1m 1s 0 PASSED MED (g)
npm-audit 0 0 0 0 0 0 2.5s 0 PASSED MED (g)
opengrep 3 10 0 0 0 0 24.5s 10 FAILED MED (g)
semgrep 0 0 0 0 0 0 <1ms 0 MISSING MED (g)
syft 0 0 0 0 0 0 2.7s 0 PASSED MED (g)

Detailed Findings

Show 14 actionable findings

Finding 1: CKV_DOCKER_3

  • Severity: HIGH
  • Scanner: checkov
  • Rule ID: CKV_DOCKER_3
  • Location: samples/agentic-knowledge-discovery/infra-cdk/lambdas/db-seed/Dockerfile:1-10

Description:
Ensure that a user for the container has been created

Code Snippet:

# Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
# SPDX-License-Identifier: Apache-2.0

FROM public.ecr.aws/lambda/python:3.13

RUN pip install --no-cache-dir "psycopg2-binary==2.9.12"

COPY index.py schema.sql seed.sql ${LAMBDA_TASK_ROOT}/

CMD ["index.handler"]

Finding 2: CKV_DOCKER_2

  • Severity: HIGH
  • Scanner: checkov
  • Rule ID: CKV_DOCKER_2
  • Location: samples/agentic-knowledge-discovery/infra-cdk/lambdas/db-seed/Dockerfile:1-10

Description:
Ensure that HEALTHCHECK instructions have been added to container images

Code Snippet:

# Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
# SPDX-License-Identifier: Apache-2.0

FROM public.ecr.aws/lambda/python:3.13

RUN pip install --no-cache-dir "psycopg2-binary==2.9.12"

COPY index.py schema.sql seed.sql ${LAMBDA_TASK_ROOT}/

CMD ["index.handler"]

Finding 3: CKV_DOCKER_3

  • Severity: HIGH
  • Scanner: checkov
  • Rule ID: CKV_DOCKER_3
  • Location: samples/agentic-knowledge-discovery/gateway/tools/structured_search/Dockerfile:1-10

Description:
Ensure that a user for the container has been created

Code Snippet:

# Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
# SPDX-License-Identifier: Apache-2.0

FROM public.ecr.aws/lambda/python:3.13

RUN pip install --no-cache-dir "psycopg2-binary==2.9.12" "sqlglot==30.12.0"

COPY structured_search_lambda.py ${LAMBDA_TASK_ROOT}/

CMD ["structured_search_lambda.handler"]

Finding 4: CKV_DOCKER_2

  • Severity: HIGH
  • Scanner: checkov
  • Rule ID: CKV_DOCKER_2
  • Location: samples/agentic-knowledge-discovery/gateway/tools/structured_search/Dockerfile:1-10

Description:
Ensure that HEALTHCHECK instructions have been added to container images

Code Snippet:

# Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
# SPDX-License-Identifier: Apache-2.0

FROM public.ecr.aws/lambda/python:3.13

RUN pip install --no-cache-dir "psycopg2-binary==2.9.12" "sqlglot==30.12.0"

COPY structured_search_lambda.py ${LAMBDA_TASK_ROOT}/

CMD ["structured_search_lambda.handler"]

Finding 5: dockerfile.security.missing-user.missing-user

  • Severity: HIGH
  • Scanner: opengrep
  • Rule ID: dockerfile.security.missing-user.missing-user
  • Location: samples/agentic-knowledge-discovery/gateway/tools/structured_search/Dockerfile:10

Description:
By not specifying a USER, a program in the container may run as 'root'. This is a security hazard. If an attacker can control a process running as root, they may have control over the container. Ensure that the last USER in a Dockerfile is a USER other than 'root'.

Code Snippet:

CMD ["structured_search_lambda.handler"]

Finding 6: python.lang.security.audit.formatted-sql-query.formatted-sql-query

  • Severity: HIGH
  • Scanner: opengrep
  • Rule ID: python.lang.security.audit.formatted-sql-query.formatted-sql-query
  • Location: samples/agentic-knowledge-discovery/gateway/tools/structured_search/structured_search_lambda.py:89

Description:
Detected possible formatted SQL query. Use parameterized queries instead.

Code Snippet:

cur.execute(f"SET statement_timeout = {QUERY_TIMEOUT_S * 1000}")

Finding 7: python.sqlalchemy.security.sqlalchemy-execute-raw-query.sqlalchemy-execute-raw-query

  • Severity: HIGH
  • Scanner: opengrep
  • Rule ID: python.sqlalchemy.security.sqlalchemy-execute-raw-query.sqlalchemy-execute-raw-query
  • Location: samples/agentic-knowledge-discovery/gateway/tools/structured_search/structured_search_lambda.py:89

Description:
Avoiding SQL string concatenation: untrusted input concatenated with raw SQL query can result in SQL Injection. In order to execute raw query safely, prepared statement should be used. SQLAlchemy provides TextualSQL to easily used prepared statement with named parameters. For complex SQL composition, use SQL Expression Language or Schema Definition Language. In most cases, SQLAlchemy ORM will be a better option.

Code Snippet:

cur.execute(f"SET statement_timeout = {QUERY_TIMEOUT_S * 1000}")

Finding 8: python.lang.security.audit.formatted-sql-query.formatted-sql-query

  • Severity: HIGH
  • Scanner: opengrep
  • Rule ID: python.lang.security.audit.formatted-sql-query.formatted-sql-query
  • Location: samples/agentic-knowledge-discovery/gateway/tools/structured_search/structured_search_lambda.py:94

Description:
Detected possible formatted SQL query. Use parameterized queries instead.

Code Snippet:

cur.execute(wrapped)

Finding 9: python.sqlalchemy.security.sqlalchemy-execute-raw-query.sqlalchemy-execute-raw-query

  • Severity: HIGH
  • Scanner: opengrep
  • Rule ID: python.sqlalchemy.security.sqlalchemy-execute-raw-query.sqlalchemy-execute-raw-query
  • Location: samples/agentic-knowledge-discovery/gateway/tools/structured_search/structured_search_lambda.py:94

Description:
Avoiding SQL string concatenation: untrusted input concatenated with raw SQL query can result in SQL Injection. In order to execute raw query safely, prepared statement should be used. SQLAlchemy provides TextualSQL to easily used prepared statement with named parameters. For complex SQL composition, use SQL Expression Language or Schema Definition Language. In most cases, SQLAlchemy ORM will be a better option.

Code Snippet:

cur.execute(wrapped)

Finding 10: dockerfile.security.missing-user.missing-user

  • Severity: HIGH
  • Scanner: opengrep
  • Rule ID: dockerfile.security.missing-user.missing-user
  • Location: samples/agentic-knowledge-discovery/infra-cdk/lambdas/db-seed/Dockerfile:10

Description:
By not specifying a USER, a program in the container may run as 'root'. This is a security hazard. If an attacker can control a process running as root, they may have control over the container. Ensure that the last USER in a Dockerfile is a USER other than 'root'.

Code Snippet:

CMD ["index.handler"]

Finding 11: python.lang.security.audit.logging.logger-credential-leak.python-logger-credential-disclosure

  • Severity: HIGH
  • Scanner: opengrep
  • Rule ID: python.lang.security.audit.logging.logger-credential-leak.python-logger-credential-disclosure
  • Location: samples/agentic-knowledge-discovery/patterns/utils/auth.py:162-164

Description:
Detected a python logger call with a potential hardcoded secret "Getting access token for stack: %s, region: %s" being logged. This may lead to secret credentials being exposed. Make sure that the logger is not logging sensitive information.

Code Snippet:

logger.info(
        "Getting access token for stack: %s, region: %s", stack_name, region
    )  # nosemgrep: python.lang.security.audit.logging.logger-credential-leak.python-logger-credential-disclosure

Finding 12: python.lang.security.audit.logging.logger-credential-leak.python-logger-credential-disclosure

  • Severity: HIGH
  • Scanner: opengrep
  • Rule ID: python.lang.security.audit.logging.logger-credential-leak.python-logger-credential-disclosure
  • Location: samples/agentic-knowledge-discovery/patterns/utils/auth.py:197-199

Description:
Detected a python logger call with a potential hardcoded secret "Requesting token from: %s" being logged. This may lead to secret credentials being exposed. Make sure that the logger is not logging sensitive information.

Code Snippet:

logger.info(
        "Requesting token from: %s", token_url
    )  # nosemgrep: python.lang.security.audit.logging.logger-credential-leak.python-logger-credential-disclosure

Finding 13: python.lang.security.audit.logging.logger-credential-leak.python-logger-credential-disclosure

  • Severity: HIGH
  • Scanner: opengrep
  • Rule ID: python.lang.security.audit.logging.logger-credential-leak.python-logger-credential-disclosure
  • Location: samples/agentic-knowledge-discovery/patterns/utils/auth.py:206-208

Description:
Detected a python logger call with a potential hardcoded secret "Token request failed: %s" being logged. This may lead to secret credentials being exposed. Make sure that the logger is not logging sensitive information.

Code Snippet:

logger.error(
            "Token request failed: %s", response.status_code
        )  # nosemgrep: python.lang.security.audit.logging.logger-credential-leak.python-logger-credential-disclosure

Finding 14: python.lang.security.audit.dynamic-urllib-use-detected.dynamic-urllib-use-detected

  • Severity: HIGH
  • Scanner: opengrep
  • Rule ID: python.lang.security.audit.dynamic-urllib-use-detected.dynamic-urllib-use-detected
  • Location: samples/agentic-knowledge-discovery/scripts/generate_sample_data.py:109

Description:
Detected a dynamic value being used with urllib. urllib supports 'file://' schemes, so a dynamic value controlled by a malicious actor may allow them to read arbitrary files. Audit uses of urllib calls to ensure user data cannot control the URLs, or consider using the 'requests' library instead.

Code Snippet:

with urllib.request.urlopen(req, timeout=120) as resp:  # nosec B310 - fixed https:// .gov URLs

Report generated by Automated Security Helper (ASH) at 2026-07-19T01:19:26+00:00

@razkenari
razkenari marked this pull request as draft July 19, 2026 01:22
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant