Build a semantic layer for agentic AI on AWS with Stardog and Amazon Bedrock AgentCore AWS and Stardog have partnered to build a semantic layer for agentic AI on AWS, using Stardog's Semantic AI Application over Amazon Aurora and Amazon Redshift, and running agents on Amazon Bedrock AgentCore to answer customer 360 questions without ETL. The solution addresses the challenge of fragmented enterprise data by providing business context and metrics, enabling AI agents to reason across disparate systems with consistent answers. Artificial Intelligence https://aws.amazon.com/blogs/machine-learning/ Build a semantic layer for agentic AI on AWS with Stardog and Amazon Bedrock AgentCore In this post we show how to build a semantic layer on AWS using Stardog’s Semantic AI Application over Amazon Aurora and Amazon Redshift, and how to run a Strands Agents https://github.com/strands-agents agent on Amazon Bedrock AgentCore that queries the layer to answer customer 360 questions across both sources without extract, transform, and load ETL . The same Stardog deployment works behind AWS computes Amazon Elastic Kubernetes Service Amazon EKS , Amazon Elastic Container Service Amazon ECS , and AWS Lambda . We use AgentCore here because it bundles inbound auth, hosting, and tool credentials into one managed service. Enterprise analytics has been chasing the same goal for two decades: shrink the time between a business question and a trustworthy answer. Scheduled reports gave way to dashboards, then dashboards gave way to self-service business intelligence BI . Even self-service depended on a data engineer having already built the right model for the right question, and the human analyst remained the bottleneck for everything outside the prepared dataset. Generative AI agents are the next step. Instead of visualizing data, they reason over it. They plan, write queries, evaluate results, refine, and iterate against the company’s live data on demand. Agentic analytics is the term for this shift: an autonomous agent at every business user’s elbow, doing the analyst’s work without waiting in the request queue. The hard part is no longer the foundation model FM . Foundation models available on Amazon Bedrock can already plan multi-step workflows, reason about schemas, and produce SQL well enough to act as a junior analyst would. The hard part sits underneath: the data the model reasons over. Enterprise data is scattered across systems that define the same things differently. The “customer” in your customer relationship management CRM system is not the same record as the “customer” in your billing system. “Revenue” calculated by the North American team isn’t the same number the European team would produce. An AI agent given direct access to this fragmented data will write technically valid queries that return wrong, conflicting, or unexplainable answers. Confidence erodes the first time two agents return two different numbers for the same question. On AWS, that data sits across a familiar mix. Operational records live in Amazon Aurora and other Amazon Relational Database Service Amazon RDS engines. Analytics history lives in Amazon Redshift. Unstructured data lives in Amazon Simple Storage Service Amazon S3 , queried through Amazon Athena, and increasingly in open table formats such as Apache Iceberg, on Amazon S3 Tables, a capability of Amazon S3, which Athena, Amazon EMR, and Amazon Redshift can all read. Each layer is purpose-built for what it stores and most enterprises will keep that shape. The challenge is helping an AI agent reason across all of them at once with the same fluency a senior human analyst would bring to the same question. Foundation models bring the language and the AWS data application brings the facts. The familiar way to connect them today is Retrieval Augmented Generation https://aws.amazon.com/what-is/retrieval-augmented-generation/ RAG : index policy documents, manuals, and support tickets into Amazon Bedrock Knowledge Bases and pull matching passages into the model’s context at query time. RAG works well when the answer lives in text the search can find. It works less well for analytical questions where the answer depends on joining live records across systems, applying a business rule consistently, and honoring row- or column-level access policies. What sits between language and facts, and is usually missing for those analytical questions, is business context and business metrics . Take a typical retail example: a shared definition of what a customer is, how an order links to one, what counts as a big spender or a high-risk account , which system owns which fact, and how the numbers the business reports are computed. The same gap shows up in other domains claims and policies in insurance, patients and encounters in healthcare, parts and shipments in supply chain under different names. A semantic layer captures that context once and lets every agent and tool reuse it. With it, an AI agent can compose answers from many sources and stand behind the numbers it returns. A semantic layer doesn’t replace RAG. It complements it. Most production systems need both, reachable through the same agent. A semantic layer is an ontology-driven view of your enterprise data. The ontology captures the concepts, relationships, attributes and rules that matter to your business. Mappings declare how those concepts are mapped from rows in each live source. The agent queries the layer. The layer translates each query into SQL against the underlying systems at runtime. Data stays where it is. Meaning is captured once and reused. When that semantic layer is implemented as Stardog does it an ontology, stable identifiers for every entity, and rules that derive new facts, and constraints that validate the data against the ontology the result is a knowledge graph . The data is connected as a graph of business entities rather than rows in tables, every entity has a stable URL-style unique identifier called an IRI https://www.w3.org/TR/rdf11-concepts/ section-IRIs , and queries traverse those connections in a W3C-defined, standards-based query language called SPARQL https://docs.stardog.com/query-stardog/ . Two more terms come up repeatedly in the rest of the post: - A named graph is a labeled subset of the graph, identified by an IRI of its own. Stardog uses named graphs as the unit of access control. The same query produces different results for different roles depending on which named graphs each role is allowed to read. - A virtual graph is a named graph whose contents are not stored in Stardog at all. They live in an external system Aurora, Amazon Redshift, Athena and Stardog fetches the rows on demand using the mappings. Federation in this post is implemented as a set of virtual graphs, one per source. The Stardog glossary https://docs.stardog.com/additional-resources/glossary defines each of these terms, and the Stardog Getting Started series https://docs.stardog.com/getting-started-series puts them in context. By the end of this post you will know: - How a semantic layer fits alongside RAG, and when to pick each. - How to federate Stardog across Amazon Aurora and Amazon Redshift, with notes on extending to Amazon Athena and other AWS data sources. - Why we recommend AgentCore Runtime, Gateway, and Identity for running the agent in production. - Two integration paths from the agent to Stardog: a direct SPARQL https://docs.stardog.com/query-stardog/ tool, and the Stardog Cloud Model Context Protocol MCP server as a Gateway tool target. - Tradeoffs on governance, deployment, and what is generally available GA versus beta today. Three layers an agent needs An AI agent that gives reliable, business-context-aware answers depends on three things working together. Each one solves a problem the others can’t. 1. Model layer. A foundation model that can plan and write. Amazon Bedrock provides a single API to multiple model families. We use Anthropic Claude Sonnet 4.6. The model knows language, it doesn’t know your business. 2. Meaning layer. A semantic layer that gives the model trustworthy, governed access to the data behind your business questions. The ontology declares the concepts and the rules that derive new facts from them, and the federation pulls live rows from each source at query time. The layer does the work: it figures out which data is relevant, rewrites the SPARQL query into SQL for each source, and joins the rows on shared identifiers. The model has a narrower job. It reads the user’s question, calls the layer when it needs data, and writes the answer in plain English. The actual reasoning over data, like applying the Big Spender rule across the federated sources, stays inside Stardog rather than inside the prompt. We use Stardog’s federated knowledge graph over Aurora and Amazon Redshift for this. 3. Agent runtime layer. The compute that hosts the agent, terminates inbound requests, manages tool credentials, and provides the operational surface for security and governance. On AWS you have a spectrum of choices: managed runtimes like Amazon Bedrock AgentCore at one end, and self-managed options like Amazon ECS, Amazon EKS, or AWS Lambda at the other. The right choice depends on how much of the agent operations you want to own. We use Amazon Bedrock AgentCore in this post because it is the most prescriptive of the options for production agents on AWS. Of the three, the meaning layer is the gap this post is about, and the rest of the walkthrough builds it. The agent runtime layer is the one most teams underestimate: how does the agent get called, how does it authenticate, where does its credential to the semantic layer live, and how does it scale. AgentCore packages answers to those questions into one managed service, which is why we use it here. Example use case: A customer 360 agent across Aurora and Amazon Redshift We chose customer 360 C360 for the rest of this walkthrough because it surfaces every gap an AI agent runs into the moment it tries to do real analytical work, and it lets us show how the semantic layer closes each one in a few hundred lines of mappings and rules. In a typical retail setup, customer profile, address, credit card, and rewards information sit in an operational database. Orders, products, categories, and vendors live in a data warehouse for analytics. Each side is well-tuned for what it does. Neither side, on its own, can answer a question about the customer as a whole. An agent that tries to answer “who are our most valuable customers, and what are they buying?” has to reconcile two databases, two schemas, two definitions of “customer”, and a derived idea “most valuable” that lives in nobody’s column. C360 makes those gaps concrete. The C360 agent runs for the analytics team. It accepts a question in plain English from a sales lead, a marketer, or a fraud analyst. It writes the queries, runs them across the company’s data, and replies with a short narrative answer plus the supporting numbers. The user does not see SQL or SPARQL, and the agent does not see the data it is not allowed to see. A user asks the C360 agent, in plain English: “Who are our top spenders in Wisconsin?” Customer profile and address live in Aurora. Order totals live in Amazon Redshift. The agent has to join them on a stable customer identifier, and that join is one of three things a semantic layer adds: 1. Joins across systems through shared meaning. The semantic layer maps customer records from both Aurora and Amazon Redshift to a common customer identity using shared business keys. This lets the join be expressed through the semantic model rather than a physical integration pipeline. Without it, that join often requires a maintained pipeline that materializes a third copy of the data and must be kept in sync each time either source changes. 2. Derived facts as rules, not queries. A definition like “big spender” can live in the ontology as a rule rather than being re-expressed in every query, and every query that mentions it gets the same answer. Without it, that definition gets duplicated across dashboards, notebooks, and reports. When the threshold changes, the copies drift apart and the same question starts returning different answers. 3. Graph-level access control. Named graph security controls access at the graph level, so different roles see different subsets of the enterprise knowledge graph. For more fine-grained protection, you can designate sensitive properties such as :ssn and :cardNumber as protected properties. Users with permission see the actual values, while others see masked values by default. With this approach, different roles can run the same query while the knowledge graph enforces consistent security policies across every application that accesses it. We took Stardog’s C360 Knowledge Kit https://github.com/stardog-union/knowledge-kits/tree/main/examples/c360 , which originally loads local CSVs, and adapted it to federate across Aurora PostgreSQL customer side and Amazon Redshift purchase side . The kit ships an ontology, sample data, and ready-made queries. You can use it as the starting point for your own work. The data model the agent does not see Underneath the agent, the C360 data is split across two AWS databases. Aurora holds the operational, customer-facing tables. Amazon Redshift holds the analytics fact table and product dimensions. Aurora PostgreSQL operational Table | Key columns | customer | cid, first name, last name, email, ssn, phone, location | address | id, city, state, zip, street name | credit card | id, cid, card num, card type | rewards account | id, cid, account id, create date | Amazon Redshift analytics Table | Key columns | purchase | id, cid, pid, date, quantity, price, card | product | id, name, brand, price, dept | category | id, dept name, parent | vendor | id, vendor name, industry | The shared identifier across the two databases is the integer cid . It appears as a primary key in the customer table on Aurora and as a non-foreign-key column in the purchase table on Amazon Redshift. There’s no SQL constraint linking them. There can’t be: they live in different engines. Answers that join customers to their orders must reconcile that integer at query time, every time, without ETL. This is what the semantic layer absorbs. The ontology declares one concept, :Customer , and one stable identity for it: an IRI https://www.w3.org/TR/rdf11-concepts/ section-IRIs of the form urn:stardog:demos:c360:customer:{cid} . Both the Aurora customer mapping and the Amazon Redshift purchase mapping mint that same IRI from their respective cid values. The agent sees one customer entity with a profile, addresses, cards, rewards accounts, and orders. The warehouses see their own rows, unchanged. The mappings mint the same customer IRI from the cid in both databases. Stardog uses that shared identity to join the federated results without requiring the underlying databases to know about one another. Reference architecture Figure 1. Key point: data stays in Aurora and Amazon Redshift. Only queries flow through the semantic layer. This is the recommended production architecture. The proof of concept POC for this post used Path A with the agent running as a standalone script. The diagram shows two flows. Inbound. A client an application, another agent, or Stardog Studio calls the agent through AgentCore Gateway. Gateway validates the inbound JSON Web Token JWT and routes the call to AgentCore Runtime, which hosts the Strands agent. The agent invokes Claude Sonnet 4.6 on Amazon Bedrock for planning and answer composition. Outbound to the semantic layer. Two paths are shown. Path A today, orange dashed : The Strands agent calls a query kg SPARQL tool that talks to Stardog directly. Use this when you don’t yet have Voicebox API access described later in this post . Path B Stardog Cloud MCP, when API access is available, blue : AgentCore Gateway has the Stardog Cloud MCP server registered as an MCP target. Gateway pulls the Stardog token from AgentCore Identity and forwards the call. The agent doesn’t touch the credential. Stardog itself federates to the warehouses at query time over Java Database Connectivity JDBC . SPARQL is rewritten to SQL per source. Results are joined inside Stardog on shared IRIs. There is no ETL job and no third copy of the data. Build the semantic layer Three pieces make the federation work. The ontology declares the concepts :Customer , :Order , :Product and the relationships between them. The mappings declare how rows in each datastore become instances of those concepts. Reasoning rules derive new facts from the data already in scope. Stardog Designer is the authoring surface for all three. The ontology Figure 2. The C360 model in Stardog Designer. Concepts like Customer , Order , Product , and Address appear as colored nodes connected by labeled relationships purchased , card holder , has address , in category . The lighter-shaded nodes around the edges Big Spender , Large Order , 2022 Orderer , the Sports Category shopper are derived classes inferred by reasoning rules in the model rather than columns in any source. The C360 ontology is authored in Stardog Designer https://docs.stardog.com/stardog-applications/designer/ , a no-code visual modeling and mapping tool. The modeler creates concepts :Customer , :Order , :Product , connects them with relationships :purchasedBy links an :Order back to a :Customer , and declares fields like :ssn and :cardNumber as sensitive properties. No OWL or RDF is written by hand. The full C360 model defines roughly ten classes and thirty properties. Designer can also generate a starting model from existing source metadata such as table schemas, FHIR https://hl7.org/fhir/ definitions, use case description and competency questions, which is a faster path than writing the model from scratch. Portability is a key advantage of Designer which uses Turtle https://www.w3.org/TR/turtle/ , the W3C standard serialization for RDF https://www.w3.org/RDF/ to persist models. This standards-based approach helps prevent vendor lock-in and supports interoperability with the broader RDF network: - Import ontologies directly from tools like Protégé https://protege.stanford.edu/ . - Export data to services such as Amazon Neptune https://aws.amazon.com/neptune/ . - Perform round-trip workflows across other RDF compatible utilities. The ontology grows over time as the questions it needs to answer get more specific. Most teams start with a small use case and competency questions used to build a model and then it is extended incrementally. Under the hood: what Designer generates. The portion of the model the federation rests on is small prefix declarations elided for brevity . :Customer a owl:Class . :purchasedBy a owl:ObjectProperty ; so:domainIncludes :Order ; so:rangeIncludes :Customer . :ssn a owl:DatatypeProperty, m:SensitiveProperty ; so:domainIncludes :Customer . The points worth noticing: every concept gets a stable identifier, the relationship from :Order to :Customer is declared once and reused everywhere, and :ssn is classified as m:SensitiveProperty from Stardog’s metadata vocabulary in the model itself rather than in a downstream policy file. The full ontology is in the C360 Knowledge Kit https://github.com/stardog-union/knowledge-kits/tree/main/examples/c360 . The mappings federation building block Figure 3. The mapping editor in Stardog Designer. The Customer source on the right is bound to the Customer concept on the left. The id column is set as the Primary Identifier, which is what produces the stable IRI used everywhere else. Below the identifier, relationships like Has Loyalty Program Status and Interacts With link the customer to other concepts in the same model. In Designer, mappings are authored visually. The modeler maps the Aurora customer table to the :Customer concept and tells Designer that id is the entity key. Designer does the same on the Amazon Redshift side: map the purchase table, mark cid as the customer key. In database terms, cid in :purchase references id in :Customer . The same map-and-mark-the-key flow works for both warehouses. The mappings stay independent, but they line up because the IRI produced from the values in the cid in :Purchase is the same IRI as produced for the values of id in :customer . The architectural property to understand is the IRI template . It is what lets the agent answer cross-warehouse questions without ETL. Both mappings produce the same identifier for the same customer. A customer with cid=42 becomes urn:stardog:demos:c360:customer:42 whether the row came from the Aurora customer table or the Amazon Redshift purchase table. The agent sees one entity. The warehouses are unchanged. No SQL JOIN ever crosses the two warehouses. The “join” is the IRI agreement. Under the hood: what Designer generates. When Designer saves a mapping, it emits Stardog Mapping Syntax SMS https://docs.stardog.com/virtual-graphs/mapping-data-sources , a superset of the W3C R2RML standard that uses a SPARQL-like syntax. Stardog reads R2RML directly and can export SMS back to R2RML, so mappings port either direction. The two excerpts that carry the federation building block look like this: Aurora customer mapping excerpt BIND TEMPLATE "urn:stardog:demos:c360:customer:{cid}" AS ?iri Redshift order mapping excerpt BIND TEMPLATE "urn:stardog:demos:c360:customer:{cid}" AS ?cust iri The full mapping files for every C360 table are in the kit https://github.com/stardog-union/knowledge-kits/tree/main/examples/c360 . The following diagram traces a question from the agent down to the data sources and back. The middle band is the semantic layer. Nothing in it stores rows. The rows live in Aurora and Amazon Redshift. Stardog uses the ontology and the mappings to decide which SQL to run where, then joins the result sets on the shared IRI before handing them back. Figure 4. The query flow from the C360 agent to Aurora and Amazon Redshift and back. SPARQL is rewritten to SQL per source. Result sets are joined inside Stardog on the shared customer IRI. Reasoning over the graph Stardog supports OWL https://docs.stardog.com/inference-engine/ reasoning and user-defined rules written in Stardog Rule Syntax SRS or SWRL https://docs.stardog.com/inference-engine/user-defined-rules . Reasoning https://docs.stardog.com/inference-engine/ is the process of inferring new facts from existing data using the schema. The kit defines derived classes such as Big Spender a customer who has placed at least one order above a threshold and Large Order . With reasoning enabled at query time, asking “how many big spenders by state?” works without precomputing or materializing those facts. The rules are defined once in the semantic model and evaluated over live data when the query runs. Encoding business definitions once, instead of re-implementing them in SQL queries, dashboards and prompts, is one of the hardest parts of moving beyond RAG. Govern access with named-graph security Customer 360 data is regulated. Two requirements show up early. 1. Some users HR, fraud need to see personally identifiable information PII like a Social Security number SSN and full card number. Most users marketing, analytics must not. 2. The control shouldn’t require changes in the underlying warehouses. Stardog’s mechanism for this is named-graph security https://docs.stardog.com/operating-stardog/security/fine-grained-security . A named graph is a labeled subset of the data. Named-graph security gates reads against each named graph on a per-user basis. Each virtual graph in the federation has its own named-graph IRI. We split the Aurora mapping into two virtual graphs. aurora c360 safe : Customer profile minus PII everything except :ssn and :cardNumber . aurora c360 pii : Only the PII triples, keyed to the same customer IRI. The Amazon Redshift mapping is one graph, redshift c360 . We then create two roles. hr user : Read on all three virtual graphs. marketing user : Read on aurora c360 safe and redshift c360 only. When marketing user runs a SPARQL query that asks for ?c :ssn ?ssn , Stardog’s planner treats aurora c360 pii as if it did not exist for that user. The JDBC pushdown for the SSN column doesn’t happen. No application-level filter, no warehouse-side change, no chance of leaking the value through a misconfigured BI tool. Same SPARQL query, two roles, two different result sets. For row-level filters a US-East analyst only sees east-coast customers, for example the same named-graph mechanism scales: split the source into more virtual graphs along the row dimension, then grant per-graph reads. This is repetition of the PII pattern, not a new feature. Stardog also supports tagging individual properties as sensitive on the ontology, with the tag driving column-level masking at query time. This is worth evaluating as an alternative to the preceding named-graph split. It fits best when sensitive fields are scattered across many entities and you would rather mark them in the ontology than partition the data. See Stardog’s fine-grained security docs https://docs.stardog.com/operating-stardog/security/fine-grained-security for the configuration steps. Run the agent and call Stardog from it Strands Agents is a small framework for building agents. A short Python script wires Claude Sonnet 4.6 on Amazon Bedrock to a tool that runs SPARQL against Stardog. A summary of the ontology is loaded into the agent’s system prompt. The model writes SPARQL, the tool returns rows, the model summarizes the results. That code is portable. The same agent can run as a Python script on a laptop, in a container on Amazon ECS or Amazon EKS, behind an Application Load Balancer, or as an AWS Lambda function. For production we recommend deploying it on Amazon Bedrock AgentCore because it bundles the operational scaffolding into one managed service. AgentCore Runtime hosts the agent and handles concurrency and session state. AgentCore Gateway is the inbound surface that validates the JWT from your identity provider IdP and routes the call to Runtime. AgentCore Identity holds the Stardog token as a credential provider, so the credential doesn’t live in the agent code. If you pick a different runtime, the same building blocks still need a home: a hosting layer, an inbound authenticator, and a credential vault. The integration patterns that follow don’t change. What changes is which AWS service holds each piece. The integration to Stardog is where deployments differ. Two paths are worth knowing. Default to Path A unless you already have Voicebox API access. Path A: Direct SPARQL tool. A small Python tool wraps the pystardog client and is exposed to the agent through Strands’ tool decorator. The agent writes SPARQL, the tool runs it, the tool returns rows. This works on Stardog instances you can reach over HTTPS, including Stardog Cloud’s Free tier. We used this path in the POC because it requires no special enablement on the Stardog account. Path B: Stardog Cloud MCP server as a Gateway tool target. Stardog publishes an official MCP server, stardog-union/stardog-cloud-mcp https://github.com/stardog-union/stardog-cloud-mcp , that exposes Voicebox https://www.stardog.com/voicebox/ Stardog’s natural-language query layer as three tools: voicebox ask , voicebox generate query , and voicebox settings . Voicebox runs its own ontology-aware natural-language-to-SPARQL pipeline and returns the reasoning chain and provenance with each answer. AgentCore Gateway can register this MCP server as a tool target, which means the agent inside Runtime sees Voicebox as a tool with no glue code, and AgentCore Identity injects the token at the Gateway hop. The MCP server’s local mode is stable. Remote mode is in beta. Path B also requires a Voicebox API token, which is gated to specific accounts. Contact Stardog if your portal doesn’t show “Manage API Keys.” Pick Path A when you don’t yet have API access or when you want full control over SPARQL generation. Pick Path B when you have API access and want Voicebox’s reasoning chain and provenance for no additional cost. We recommend enabling Amazon Bedrock prompt caching for production deployments. The agent reuses the same large system prompt, the C360 ontology summary, on every call. Amazon Bedrock prompt caching https://docs.aws.amazon.com/bedrock/latest/userguide/prompt-caching.html keeps the cached portion of that prompt warm across calls, which reduces input-token cost on repeat invocations. In Stardog deployments, prompt caching can reduce per-query input-token cost when the same ontology context is reused across requests. Caching is configured per request. Check your agent framework’s BedrockModel parameters for how to expose the cache point. Sample queries and verification To confirm the federation behaved as designed, we ran three categories of questions against the live deployment. Aurora-only. “List ten customers and their state.” Source data is in Aurora. Stardog issues one SQL query against the Aurora customer and address tables and returns the rows. The Amazon Redshift virtual graph is not touched. Amazon Redshift-only. “Top ten products by units sold.” Source data is in Amazon Redshift. Stardog issues a single grouped aggregation against the purchase table and returns the totals. Aurora isn’t touched. Federated. “Top ten customer spenders, with their state.” This needs Aurora customers and addresses joined with Amazon Redshift orders on the shared customer IRI. The actual SPARQL the agent runs: PREFIX :