Conductor is a CLI tool that scans C# MassTransit + Amazon SQS/SNS configuration and generates a least-privilege IAM policy JSON.
- Scans a repo for MassTransit Amazon SQS usage.
- Detects queues/topics from common patterns:
UsingAmazonSqs(...)ReceiveEndpoint(...)ec.Subscribe(...)bus.Message<T>(x => x.SetEntityName(...))EndpointConvention.Map<T>(new Uri(...))
- Resolves names from:
- string literals
constvalues- simple
.Replace("{{env}}", ...)patterns
- Outputs deterministic IAM JSON policy or Terraform (depending on the
--formatyou select).
- .NET SDK 10+ installed
- macOS/Linux/Windows shell
Check version:
dotnet --versionInstall:
dotnet tool install -g Conductor.ToolUpdate:
dotnet tool update -g Conductor.ToolUninstall:
dotnet tool uninstall -g Conductor.ToolFrom repo root:
dotnet restore Conductor.slnx
dotnet build Conductor.slnx -c ReleaseRun after install:
conductor --help
conductor generate --repo /absolute/path/to/repo --out ./policy.jsonUse the built CLI:
dotnet ./src/Conductor.Cli/bin/Release/net10.0/Conductor.dll generate \
--repo /absolute/path/to/your/repo \
--out /absolute/path/to/policy.jsonconductor generate --repo <path> --out <path> [options]
--repoPath to the repository to scan--outOutput path:- if
--scope repo: output file path - if
--scope folder: output directory path
- if
--scoperepo|folder. Default:repo--formatOutput format (iam-jsonorterraform). Default:iam-json--stricttrue|false. Default:true--regionARN region token/value. Default:${region}--account-idARN account token/value. Default:${account_id}--envreserved for future expansion. Default:${env}
dotnet ./src/Conductor.Cli/bin/Release/net10.0/conductor.dll generate \
--repo /Users/me/source/my-service \
--out ./policy.jsondotnet ./src/Conductor.Cli/bin/Release/net10.0/conductor.dll generate \
--repo /Users/me/source/my-service \
--out ./policy.prod.json \
--region us-east-2 \
--account-id 123456789012dotnet ./src/Conductor.Cli/bin/Release/net10.0/conductor.dll generate \
--repo /Users/me/source/my-service \
--out ./policy.json \
--strict falsedotnet ./src/Conductor.Cli/bin/Release/net10.0/conductor.dll generate \
--repo /Users/me/source/repos/<repo-name> \
--scope folder \
--out ./policies \
--strict falseThis creates files like:
./policies/Company.Api.policy.json./policies/Company.BlogAgent.policy.json- etc. (for folders where MassTransit SQS/SNS usage is detected)
When --format terraform is selected, generated files use .policy.tf.
When --strict true:
- unresolved queue/topic names are treated as errors
- command exits non-zero
- diagnostics are printed to stderr with source file paths
dotnet test Conductor.slnx -c Releasescope=repo: one policy output at--outpath (JSON foriam-json, HCL forterraform)scope=folder: one policy output per top-level folder in repo (.policy.jsonforiam-json,.policy.tfforterraform)
Example input assumptions:
- queue detected:
order-submit - topic detected:
order-events - default tokenized ARN parts:
region=${region},account_id=${account_id} - fault publish behavior enabled (so MassTransit fault topics are included)
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "SqsManageQueues",
"Effect": "Allow",
"Action": [
"sqs:ChangeMessageVisibility",
"sqs:CreateQueue",
"sqs:DeleteMessage",
"sqs:GetQueueAttributes",
"sqs:GetQueueUrl",
"sqs:PurgeQueue",
"sqs:ReceiveMessage",
"sqs:SendMessage",
"sqs:SetQueueAttributes",
"sqs:TagQueue"
],
"Resource": [
"arn:aws:sqs:${region}:${account_id}:order-submit",
"arn:aws:sqs:${region}:${account_id}:order-submit_error",
"arn:aws:sqs:${region}:${account_id}:order-submit_skipped"
]
},
{
"Sid": "SnsManageTopics",
"Effect": "Allow",
"Action": [
"sns:CreateTopic",
"sns:GetTopicAttributes",
"sns:Publish",
"sns:SetTopicAttributes",
"sns:Subscribe",
"sns:TagResource",
"sns:Unsubscribe"
],
"Resource": [
"arn:aws:sns:${region}:${account_id}:MassTransit-Fault*",
"arn:aws:sns:${region}:${account_id}:MassTransit-ReceiveFault",
"arn:aws:sns:${region}:${account_id}:order-events"
]
}
]
}data "aws_iam_policy_document" "conductor_sqs" {
statement {
sid = "SqsManageQueues"
effect = "Allow"
actions = [
"sqs:ChangeMessageVisibility",
"sqs:CreateQueue",
"sqs:DeleteMessage",
"sqs:GetQueueAttributes",
"sqs:GetQueueUrl",
"sqs:PurgeQueue",
"sqs:ReceiveMessage",
"sqs:SendMessage",
"sqs:SetQueueAttributes",
"sqs:TagQueue",
]
resources = [
"arn:aws:sqs:${region}:${account_id}:order-submit",
"arn:aws:sqs:${region}:${account_id}:order-submit_error",
"arn:aws:sqs:${region}:${account_id}:order-submit_skipped",
]
}
}
data "aws_iam_policy_document" "conductor_sns" {
statement {
sid = "SnsManageTopics"
effect = "Allow"
actions = [
"sns:CreateTopic",
"sns:GetTopicAttributes",
"sns:Publish",
"sns:SetTopicAttributes",
"sns:Subscribe",
"sns:TagResource",
"sns:Unsubscribe",
]
resources = [
"arn:aws:sns:${region}:${account_id}:MassTransit-Fault*",
"arn:aws:sns:${region}:${account_id}:MassTransit-ReceiveFault",
"arn:aws:sns:${region}:${account_id}:order-events",
]
}
}- Focused on common MassTransit SQS/SNS patterns (not every dynamic/metaprogrammed style).
- If endpoint names are fully dynamic/runtime-only, strict mode will fail by design.
- Expanded analyzer coverage for additional MassTransit patterns.
- Create feature branch
- Add/adjust tests
- Run build + tests
- Open PR