auth.mjs 3.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182
  1. import { Sha256 } from '@aws-crypto/sha256-js';
  2. import { FetchHttpHandler } from '@smithy/fetch-http-handler';
  3. import { HttpRequest } from '@smithy/protocol-http';
  4. import { SignatureV4 } from '@smithy/signature-v4';
  5. import assert from 'assert';
  6. const DEFAULT_PROVIDER_CHAIN_RESOLVER = () => import('@aws-sdk/credential-providers').then(({ fromNodeProviderChain }) => fromNodeProviderChain({
  7. clientConfig: {
  8. requestHandler: new FetchHttpHandler({
  9. requestInit: (httpRequest) => {
  10. return {
  11. ...httpRequest,
  12. };
  13. },
  14. }),
  15. },
  16. }))
  17. .catch((error) => {
  18. throw new Error(`Failed to import '@aws-sdk/credential-providers'.` +
  19. `You can provide a custom \`providerChainResolver\` in the client options if your runtime does not have access to '@aws-sdk/credential-providers': ` +
  20. `\`new AnthropicBedrock({ providerChainResolver })\` ` +
  21. `Original error: ${error.message}`);
  22. });
  23. export const getAuthHeaders = async (req, props) => {
  24. assert(req.method, 'Expected request method property to be set');
  25. const providerChain = await (props.providerChainResolver ?
  26. props.providerChainResolver()
  27. : DEFAULT_PROVIDER_CHAIN_RESOLVER());
  28. const credentials = await withTempEnv(() => {
  29. // Temporarily set the appropriate environment variables if we've been
  30. // explicitly given credentials so that the credentials provider can
  31. // resolve them.
  32. //
  33. // Note: the environment provider is only not run first if the `AWS_PROFILE`
  34. // environment variable is set.
  35. // https://github.com/aws/aws-sdk-js-v3/blob/44a18a34b2c93feccdfcd162928d13e6dbdcaf30/packages/credential-provider-node/src/defaultProvider.ts#L49
  36. if (props.awsAccessKey) {
  37. process.env['AWS_ACCESS_KEY_ID'] = props.awsAccessKey;
  38. }
  39. if (props.awsSecretKey) {
  40. process.env['AWS_SECRET_ACCESS_KEY'] = props.awsSecretKey;
  41. }
  42. if (props.awsSessionToken) {
  43. process.env['AWS_SESSION_TOKEN'] = props.awsSessionToken;
  44. }
  45. }, () => providerChain());
  46. const signer = new SignatureV4({
  47. service: 'bedrock',
  48. region: props.regionName,
  49. credentials,
  50. sha256: Sha256,
  51. });
  52. const url = new URL(props.url);
  53. const headers = !req.headers ? {}
  54. : Symbol.iterator in req.headers ?
  55. Object.fromEntries(Array.from(req.headers).map((header) => [...header]))
  56. : { ...req.headers };
  57. // The connection header may be stripped by a proxy somewhere, so the receiver
  58. // of this message may not see this header, so we remove it from the set of headers
  59. // that are signed.
  60. delete headers['connection'];
  61. headers['host'] = url.hostname;
  62. const request = new HttpRequest({
  63. method: req.method.toUpperCase(),
  64. protocol: url.protocol,
  65. path: url.pathname,
  66. headers,
  67. body: req.body,
  68. });
  69. const signed = await signer.sign(request);
  70. return signed.headers;
  71. };
  72. const withTempEnv = async (updateEnv, fn) => {
  73. const previousEnv = { ...process.env };
  74. try {
  75. updateEnv();
  76. return await fn();
  77. }
  78. finally {
  79. process.env = previousEnv;
  80. }
  81. };
  82. //# sourceMappingURL=auth.mjs.map