A pipeline should be associated with one environment (I'm not talking about GoCD's environments here).
You may want to consider one of the following approaches:
a. An environment's pipeline that is manually triggered, and which uses an earlier pipeline as it's material. (e.g. a Prod deploy pipeline that uses the staging pipeline as a material.). Only the agreed-upon pipeline number from staging would be used in Prod.
b. If you have multiple pipelines that have to go live together, then create one downstream pipeline that all of these join to. Then use that pipeline number for all further environments. e.g. Web -> Bundle, Backend1 -> Bundle, Backend2 -> Bundle . In the Bundle pipeline, set the trigger to be manual, use Trigger with Options to select which versions of the Web, App1 and App2 pipelines you want to use, and then refer to that Bundle version for all downstream environments.
c. For teams that have a test suite that can test across Web, App1 and App2 (the scenario above), I'd change "Bundle" above to "Acceptance Test". Meaning, "So and so combo of web + app1 + app2 have passed this acceptance test suite and can be used in all further environmental".
d. If you want to release them all independently, then it may be a simple matter (in terms of pipeline) to just have Web -> ApproveWebForProd -> WedProdDeploy, App1 -> ApproveApp1ForProd -> AppProdDeploy, etc. This presumes that the various tiers have their own contract tests to ensure that if the App1 changes, then the test suite would flag any incompatibilities/breaking changes with Web.
-- Ram