Back to Checks
aws

Service Catalog portfolio is shared only within the AWS Organization

servicecatalog_portfolio_shared_within_organization_only
Service: servicecatalogSeverity: high
OfficialBuilt-inVerified
Categories:trust-boundaries
Resource Type:Other

AWS Service Catalog portfolios are assessed to confirm sharing occurs via AWS Organizations integration, not direct ACCOUNT shares. It reviews shared portfolios and identifies those targeted to individual accounts instead of organizational scopes.

Risk

Sharing with individual accounts enables recipients to import and launch products outside centralized guardrails, inheriting launch roles. This can cause unauthorized provisioning, data exposure, and configuration drift-impacting confidentiality, integrity, and availability through misused privileges and uncontrolled costs.

Run this check with Prowler

Run in Prowler Cloud
Run
prowler aws --checks servicecatalog_portfolio_shared_within_organization_only

Recommendation

Prefer organizational sharing for portfolios and avoid ACCOUNT targets. Enforce least privilege on portfolio access and launch roles, and review shares regularly. Apply separation of duties and defense in depth so only governed accounts consume products and blast radius remains constrained.

Remediation

CLI

aws servicecatalog create-portfolio-share --portfolio-id <portfolio-id> --organization-ids <org-id>

Terraform

# Share Service Catalog portfolio only within the AWS Organization
resource "aws_servicecatalog_portfolio_share" "<example_resource_name>" {
  portfolio_id = "<example_resource_id>"

  organization_node {           # CRITICAL: share within AWS Organizations
    type  = "ORGANIZATION"     # Shares the portfolio with the entire org
    value = "<example_resource_id>"  # e.g., o-xxxxxxxxxx
  }
}

NativeIaC

# CloudFormation: Share Service Catalog portfolio only within the AWS Organization
Resources:
  <example_resource_name>:
    Type: AWS::ServiceCatalog::PortfolioShare
    Properties:
      PortfolioId: <example_resource_id>
      OrganizationNode:               # CRITICAL: share within AWS Organizations
        Type: ORGANIZATION            # Shares the portfolio with the entire org
        Value: <example_resource_id>  # e.g., o-xxxxxxxxxx

Other

1In the AWS Console, go to Service Catalog > Portfolios and open the target portfolio
2Open the Shares/Sharing tab
3Remove every share of Type "Account" (stop sharing with each account)
4Click Share, choose "AWS Organizations", set Type to "Organization", enter your Org ID (o-xxxxxxxxxx), and share
5Verify no remaining shares of Type "Account" exist

Check Code

from prowler.lib.check.models import Check, Check_Report_AWS
from prowler.providers.aws.services.organizations.organizations_client import (
    organizations_client,
)
from prowler.providers.aws.services.servicecatalog.servicecatalog_client import (
    servicecatalog_client,
)


class servicecatalog_portfolio_shared_within_organization_only(Check):
    def execute(self):
        findings = []
        if (
            organizations_client.organization
            and organizations_client.organization.status == "ACTIVE"
        ):
            for portfolio in servicecatalog_client.portfolios.values():
                if portfolio.shares is not None:
                    report = Check_Report_AWS(
                        metadata=self.metadata(), resource=portfolio
                    )
                    report.status = "PASS"
                    report.status_extended = f"ServiceCatalog Portfolio {portfolio.name} is shared within your AWS Organization."
                    for portfolio_share in portfolio.shares:
                        if portfolio_share.type == "ACCOUNT":
                            report.status = "FAIL"
                            report.status_extended = f"ServiceCatalog Portfolio {portfolio.name} is shared with an account."
                            break

                    findings.append(report)

        return findings