This is controlled by the Sitecore.Commerce.Core.IgnorePublishedPolicy, if the environment you're passing in your request contains this policy then both published & unpublished entities will be returned in any requests.
Out of the box the HabitatAuthoring environment contains this policy, whereas the HabitatShops doesn't.
To make sure you get the correct values in your indexes your crawlers should pass in HabitatAuthoring for the master index and HabitatShops for your web index.
Out of the box the master index definition includes these default crawlers...
<crawler type="Sitecore.Commerce.Engine.Connect.Search.Crawlers.CatalogsCrawler, Sitecore.Commerce.Engine.Connect" patch:source="Sitecore.Commerce.Engine.Connectors.Index.Solr.config">
<ItemsToTake>100</ItemsToTake>
<ListName>Catalogs</ListName>
<IndexListName>CatalogsIndex</IndexListName>
<Environments hint="list">
<environment>HabitatAuthoring</environment>
</Environments>
<Database>master</Database>
</crawler>
<crawler type="Sitecore.Commerce.Engine.Connect.Search.Crawlers.CategoriesCrawler, Sitecore.Commerce.Engine.Connect" patch:source="Sitecore.Commerce.Engine.Connectors.Index.Solr.config">
<ItemsToTake>100</ItemsToTake>
<ListName>Categories</ListName>
<IndexListName>CategoriesIndex</IndexListName>
<Environments hint="list">
<environment>HabitatAuthoring</environment>
</Environments>
<Database>master</Database>
</crawler>
<crawler type="Sitecore.Commerce.Engine.Connect.Search.Crawlers.SellableItemsCrawler, Sitecore.Commerce.Engine.Connect" patch:source="Sitecore.Commerce.Engine.Connectors.Index.Solr.config">
<ItemsToTake>100</ItemsToTake>
<ListName>SellableItems</ListName>
<IndexListName>SellableItemsIndex</IndexListName>
<Environments hint="list">
<environment>HabitatAuthoring</environment>
</Environments>
<Database>master</Database>
</crawler>
The Web index includes these default crawlers...
<crawler type="Sitecore.Commerce.Engine.Connect.Search.Crawlers.CatalogsCrawler, Sitecore.Commerce.Engine.Connect" patch:source="Sitecore.Commerce.Engine.Connectors.Index.Solr.config">
<ItemsToTake>100</ItemsToTake>
<ListName>Catalogs</ListName>
<IndexListName>CatalogsIndex</IndexListName>
<Environments hint="list">
<environment>HabitatShops</environment>
</Environments>
<Database>web</Database>
</crawler>
<crawler type="Sitecore.Commerce.Engine.Connect.Search.Crawlers.CategoriesCrawler, Sitecore.Commerce.Engine.Connect" patch:source="Sitecore.Commerce.Engine.Connectors.Index.Solr.config">
<ItemsToTake>100</ItemsToTake>
<ListName>Categories</ListName>
<IndexListName>CategoriesIndex</IndexListName>
<Environments hint="list">
<environment>HabitatShops</environment>
</Environments>
<Database>web</Database>
</crawler>
<crawler type="Sitecore.Commerce.Engine.Connect.Search.Crawlers.SellableItemsCrawler, Sitecore.Commerce.Engine.Connect" patch:source="Sitecore.Commerce.Engine.Connectors.Index.Solr.config">
<ItemsToTake>100</ItemsToTake>
<ListName>SellableItems</ListName>
<IndexListName>SellableItemsIndex</IndexListName>
<Environments hint="list">
<environment>HabitatShops</environment>
</Environments>
<Database>web</Database>
</crawler>
Notice how the environment name being passed in changes between the master & web definitions. This is what controls whether unpublished entities are indexes or not.