docs: add how-to guide for reporting AWS Bedrock AgentCore environments - #356
docs: add how-to guide for reporting AWS Bedrock AgentCore environments#356dangrondahl wants to merge 7 commits into
Conversation
Documentation-driven development for #355. The page specifies the intended UX for `kosli snapshot agentcore` before the CLI and server work is scoped, so it is reviewed on the preview environment first. Every Kosli command is marked as proposed, since neither the command nor the `agentcore` environment type exists yet. The AWS commands are real and were checked against the current AWS reference docs, not only the spike corpus. The page leads with the CI-build-and-attest argument rather than treating it as an aside: `agentcore deploy` builds the image server-side in CodeBuild, so CI never produces an artifact to attest and the snapshot has nothing to match against. That is the substance of the guide, not a footnote. Scoped to container builds. CodeZip is named as an explicit limitation. Note the reason is narrower than the spike first concluded: `codeConfiguration` does define an optional `versionId`, but it is supplied by the deployer rather than computed by AgentCore, and it was absent from the captured response because nothing set it. There is still no service-computed content hash, so the limitation stands - but "the field does not exist" would have been wrong. Recommends pinning `containerUri` by digest. The documented pattern accepts `:tag` or `@sha256:digest`, and the digest form names exactly the image that was attested and cannot be repointed later. Granularity resolved as one Kosli environment per account and region covering all runtimes, with ECS-style include/exclude filtering flags. That matches the existing ECS and Lambda reporters and keeps one snapshot diff meaningful across the whole agent fleet. Reporting reads the live version rather than the newest one: endpoints pin versions independently, so DEFAULT can be on v4 while a named endpoint still serves v2.
The previous version repeated the rationale from #355: that `agentcore deploy` building the image server-side means "CI never produces an artifact it can attest, so there is nothing to match against what is running." That is wrong, and it was the load-bearing sentence of the section. `kosli attest artifact --artifact-type oci` resolves the digest from the registry manifest and does not care who built the image, so attesting the ECR image after `agentcore deploy` produces a fingerprint that matches the snapshot perfectly well. The real problem is ordering, not attribution. `agentcore deploy` builds the image and creates or updates the runtime in one CloudFormation operation, so there is no point at which the image exists and the runtime is not already pointed at it. Anything attested afterwards describes something already serving traffic: a policy reports a violation instead of preventing one, and scans and approvals land post-release. So the recommendation stands but the argument changes: post-hoc attestation buys an audit trail, separating build from release buys a gate. Both are now documented, with the tradeoff stated, which also makes the page a better answer to "how should we structure the pipeline". Cites AWS's own GitHub Actions reference pipeline as precedent - it builds and pushes to ECR from the Dockerfile, scans with Inspector, then creates the runtime from that image, and does not use `agentcore deploy`. Attesting to Kosli occupies the same slot as the scan. This reverses a decision recorded as settled in #355 and must be called out in the PR description rather than landing as a quiet edit.
|
Preview deployment for your docs. Learn more about Mintlify Previews.
|
|
Claude finished @dangrondahl's task in 3m 18s —— View job Review:
|
| Location | Issue | Recommendation |
|---|---|---|
report_agentcore_envs.md:104-105 |
Three forms of the architecture name appear in one step: "ARM64", aarch64, linux/arm64. The Docker flag is fixed syntax, but the prose could be consistent. |
Use "ARM64" in both prose locations; keep linux/arm64 only in the Docker command. Inline comment → |
report_agentcore_envs.md:31 |
The prerequisite links to the environments page, which won't list agentcore as an option until the server ships. The "(Proposed)" note is there but could be more directive. |
Tell readers to skip the step until the type ships, so they don't go hunting. Inline comment → |
report_agentcore_envs.md (general) |
Already noted in previous review — content is how-to guide style (goal-oriented) but lives in tutorials/. |
Fine for navigation grouping alongside the other reporters. Worth revisiting if Diátaxis separation becomes strict. |
Overall assessment
This is a strong draft. The page does several things well:
- Honest about what's real and what isn't. The
<Warning>at the top and per-section "(Proposed)" markers make it unambiguous which commands exist today. That's the right way to handle documentation-driven development. - The build-vs-release argument is well-reasoned. The correction from the original docs: add how-to guide for reporting AWS Bedrock AgentCore environments #355 rationale (attribution → ordering) is clean, and presenting both paths with a named tradeoff (audit trail vs. gate) is more useful than an assertion.
- Limitations are specific, not vague. The CodeZip section explains why there's no support (no service-computed content hash), and the configuration section names the exact fields that matter. Readers know what's missing and why, not just that something is missing.
- The "Known gaps" callout gathers everything in one place without making promises — "direction rather than commitments, with no order or dates implied" is the right framing.
- Cross-links work in both directions between
report_aws_envsandreport_agentcore_envs.
The PR description's corrections to #355 claims (especially the reversed CI-build rationale and the versionId clarification) are well-documented and the page reflects the corrected understanding.
No blockers. The two inline suggestions are cosmetic.
The old version was one line saying configuration is not tracked, which undersells it. For ECS or Lambda the image is most of what the workload does, so a digest is a fair proxy for behavior. An AgentCore runtime is not like that: a role swap, a new EFS mount, a widened inbound auth audience or a changed model ID in an environment variable all change what the agent can do while the image digest stays identical. Names the four fields worth capturing first - roleArn, networkConfiguration, authorizerConfiguration, filesystemConfigurations - in a table with what a change to each one means, and calls out environmentVariables separately since it is the most decisive of the set but is marked sensitive in the AWS SDKs and must never be stored as values. Stated as "not yet" with the reason rather than as a roadmap commitment, since #355 scopes configuration tracking out. Ends with the mitigation a reader can act on today: pin those fields in the IaC that creates the runtime and review changes there. Note filesystemConfigurations and requestHeaderConfiguration postdate the spike corpus, so the corpus is no longer a complete picture of the response.
The page marked deferred work in four separate places: the top warning, a prerequisites aside, the CLI section warning and the Terraform note, plus the configuration limitation. Each marker is correct where it sits, but there was nowhere a reader could look to answer "what will this eventually do". Adds one <Info> at the end of Limitations collecting the four gaps, with a cross-reference to the Terraform section rather than restating it. This is the sixth callout on the page and CLAUDE.md says to use them sparingly, so it is justified only because it consolidates rather than adding another inline marker. Framed as direction with no order or dates implied. The page is already a specification for unbuilt work, and turning its gaps into an implied schedule would overpromise on something #355 has not scoped.
The page asserted that the running digest matches what CI attested but never showed how to confirm it. Adds a fourth step reading the snapshot back with `kosli get snapshot`, with the table output and the three columns that prove the pipeline is wired up: Fingerprint against the attested digest, FLOW and COMMIT for traceability, COMPLIANCE. Notes that Kosli stores the digest without its `sha256:` prefix, since the reader is comparing it by eye against what they pushed. Also names the failure signal: FLOW of N/A with NON-COMPLIANT means the image reached the runtime without being attested, which is what attesting after release looks like from the environment side. That makes the ordering argument earlier in the section concrete rather than theoretical. `kosli get snapshot` exists today so it needs no proposed marker, but it can only show an AgentCore snapshot once the reporter ships, and it depends on the reporting section below, so the step points there explicitly rather than leaving the order implicit. Drops `kosli get snapshot` from the closing list, where it is now redundant.
REPLICAS is len(creationTimestamp), which the server builds with one entry per running instance of an artifact: one per task for ECS, one per pod for K8s. An AgentCore reporter would emit one entry per runtime, so the column would read 1 for a single runtime while AgentCore may be running many session microVMs or none at all. Left unexplained it invites the reader to treat it as a concurrency count, which it is not for this environment type. Also records the consequence of grouping by fingerprint: two runtimes serving the same image collapse into one row, so their identity is lost. Added to the known gaps, since ECS and Cloud Run already solve this with a per-type context object on the artifact (task_arn/cluster_name/service_name and kind/service_name/revision_name), and AgentCore will need the equivalent to support one environment per account and region.
Review feedback on #356. `prod-*` and `dev-*` are glob habits, not regexes. Verified with Go's regexp: `prod-*` compiles but means `prod-` followed by zero or more hyphens, so it also matches a runtime called `prod`. Corrected to `prod-.*` and `dev-.*`. Rather than only fixing the two examples, added a paragraph naming the trap: the `-regex` flags take Go regular expressions, not shell globs, they are unanchored, and `^`/`$` are needed for an exact match. The examples were copied from the CLI's own help text, so a reader arriving with the same assumption will make the same mistake on the next flag they reach. Also replaced the descriptive link text with the AWS post's actual title, so the reference is recoverable if the URL moves.
de36f02 to
7016355
Compare
| <Step title="Build for ARM64"> | ||
| AgentCore runtimes are `aarch64`. If your CI runners are `x86_64`, cross-build |
There was a problem hiding this comment.
Suggestion: Three forms appear in this step — "ARM64" (title and line 118), aarch64 (here), and linux/arm64 (the Docker flag). The Docker flag is fixed syntax, but the prose could pick one term. ARM64 is friendlier for most readers; consider using it here too:
| <Step title="Build for ARM64"> | |
| AgentCore runtimes are `aarch64`. If your CI runners are `x86_64`, cross-build | |
| <Step> | |
| AgentCore runtimes are ARM64. If your CI runners are x86_64, cross-build |
| * Have access to AWS, with AgentCore runtimes deployed from container images. | ||
| * [Create an AgentCore Kosli environment](/getting_started/environments#create-an-environment) named `agentcore-env-tutorial`. *(Proposed: the `agentcore` environment type is not yet available.)* |
There was a problem hiding this comment.
Suggestion: This links to /getting_started/environments#create-an-environment, which won't list agentcore as an option until the server ships. A reader following the link will find no matching environment type. Consider making the "(Proposed)" note a bit more directive — e.g. "this type is not yet available; skip this prerequisite until it ships" — so readers don't go hunting.
| * Have access to AWS, with AgentCore runtimes deployed from container images. | |
| * [Create an AgentCore Kosli environment](/getting_started/environments#create-an-environment) named `agentcore-env-tutorial`. *(Proposed: the `agentcore` environment type is not yet available.)* | |
| * [Create an AgentCore Kosli environment](/getting_started/environments#create-an-environment) named `agentcore-env-tutorial`. *(Proposed: the `agentcore` environment type is not yet available; skip this step until it ships.)* |
| way. It is also where secrets end up, and the AWS SDKs mark it sensitive, so it | ||
| needs different handling from the rest: a key set or a hash, never the values. | ||
|
|
||
| Treat the digest as answering "which build is running", not "what is this agent |
There was a problem hiding this comment.
Praise: This framing sentence is excellent — it gives readers a mental model for the limitation instead of just listing it. Strong close to the section.
Adds
tutorials/report_agentcore_envs.mdand registers it inconfig/navigation.jsonunder Reporting environments, cross-linked both ways with/tutorials/report_aws_envs.Closes #355
Do not merge yet
This is documentation-driven development. The page describes
kosli snapshot agentcore, which does not exist, and anagentcoreenvironment type that the server does not have. Per #355 it stays a draft until those ship. The preview environment is the review surface.Every Kosli command is either real today or explicitly marked proposed. All AWS commands are real, and I checked them against the current AWS reference docs rather than only the spike corpus.
Decisions that need review
1 and 2 are coupled: granularity depends on per-runtime identity
Granularity was left open in #355 and I resolved it while drafting: one Kosli environment per AWS account and region, covering all AgentCore runtimes, each runtime one artifact, with ECS-style
--runtimes/--runtimes-regex/--exclude/--exclude-regex. This matcheskosli snapshot ecsandkosli snapshot lambdaand keeps one snapshot diff meaningful across the whole agent fleet.That choice only works if snapshots carry per-runtime identity. Snapshot artifacts group by fingerprint, so two runtimes serving the same image collapse into a single row and nothing distinguishes them. You get a correct list of digests and no idea what is running where.
ECS and Cloud Run already solve exactly this with a per-type context object on the artifact (
ecs_contextwithtask_arn/cluster_name/service_name;cloud_run_contextwithkind/service_name/revision_name), set on the normal artifact path. AgentCore needs the equivalentagentcore_context.So please review these together, not separately. The proposition is "one environment per account and region, conditional on
agentcore_contextshipping." If that server work does not happen, the honest fallback is one environment per runtime, because then the environment name carries the identity the artifact row cannot. That is a worse fit with the other reporters and multiplies environments, but it degrades gracefully instead of silently losing information.3. Reversal: the rationale in #355 for the CI-build recommendation was wrong
#355 states:
That is false, and I had written it into the page verbatim before catching it.
kosli attest artifact --artifact-type ociresolves the digest from the registry manifest and does not care who built the image, so attesting the ECR image afteragentcore deployproduces a fingerprint that matches the snapshot perfectly well.The recommendation survives, but the argument changes from attribution to ordering.
agentcore deploybuilds the image and creates or updates the runtime in one CloudFormation operation, so there is no point at which the image exists and the runtime is not already pointed at it. Anything attested afterwards describes something already serving traffic: a policy reports a violation instead of preventing one, and scans and approvals land post-release.So the page now documents both paths with the tradeoff stated: post-hoc attestation buys an audit trail, separating build from release buys a gate. It also cites AWS's own GitHub Actions reference pipeline, which builds and pushes to ECR from the Dockerfile, scans with Inspector, then creates the runtime, and does not use
agentcore deploy.This makes the page a better answer to "how should we structure the pipeline", because it gives a reason to choose rather than an assertion.
Corrections to claims in #355
codeConfiguration.code.s3has noversionIdfieldCodeSha256.containerUriis a tag, so Kosli must resolve it@sha256:digest. The page now recommends pinning by digest, which names exactly the image that was attested and cannot be repointed.DEFAULTfollows the newest version but a named endpoint does not, so you can haveDEFAULTon v4 whilePRODserves v2.Verified, and not verified
Verified against current AWS docs: ARM64-only (enforced by ELF header validation, fails
CREATE_FAILED), the tagged-union artifact shape, version numbers as strings, and thatbedrock-agentcore:List*/Get*plusecr:BatchGetImage/ecr:DescribeImagescovers the read chain.Not verified: nobody has run reporting end to end against a runtime deployed from a pre-built ECR image. AWS documents the pattern as first-class, including CDK's
AgentRuntimeArtifact.fromEcrRepositoryandfromImageUri, but the spike only ever deployed viaagentcore deploy. The page says so in a<Note>and does not present the invocation as a tested recipe. Proving it is the next iteration.Also worth knowing:
filesystemConfigurationsandrequestHeaderConfigurationpostdate the spike corpus, so the corpus is no longer a complete picture of theGetAgentRuntimeresponse. Do not build the reporter from the corpus alone.Open question for reviewers
Can
agentcore package("Package agent artifacts without deploying") produce a pushed ARM64 ECR image and a digest? If it can, the recommended path gets much cheaper to adopt: keep the tooling, just split the steps. If it cannot, the recommendation really does mean droppingagentcore deployfor container builds, which is a bigger ask and the page should say so. The spike evidence suggests the container image build is bound to the CloudFormation deploy, but I did not confirm it.Scope notes
roleArn,networkConfiguration,authorizerConfigurationandfilesystemConfigurationsas the fields that change what an agent can do while the digest stays identical, and flagsenvironmentVariablesas the most decisive of all but SDK-sensitive, so never stored as values./tutorials/report_aws_envsalongside ECS, Lambda and S3. Not this PR.Checks
config/navigation.json/tutorials/report_aws_envsmint broken-linkspasses (one pre-existing failure intutorials/working_with_controls.mdx, untouched by this branch)valecleanNote on history: the branch includes three commits adding, simplifying, then removing a Mermaid pipeline diagram. Kept rather than squashed so the reasoning is recoverable. Happy to squash if preferred.